Add v8 library for Android

This commit is contained in:
James Chen 2017-08-16 10:00:59 +08:00
parent f773c739b7
commit 987e15059a
92 changed files with 53656 additions and 0 deletions

View File

@ -0,0 +1,29 @@
// Copyright 2016 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_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#if defined(_WIN32)
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllexport)
#elif USING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllimport)
#else
#define V8_PLATFORM_EXPORT
#endif // BUILDING_V8_PLATFORM_SHARED
#else // defined(_WIN32)
// Setup for Linux shared library export.
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __attribute__((visibility("default")))
#else
#define V8_PLATFORM_EXPORT
#endif
#endif // defined(_WIN32)
#endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_

View File

@ -0,0 +1,78 @@
// Copyright 2014 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_LIBPLATFORM_LIBPLATFORM_H_
#define V8_LIBPLATFORM_LIBPLATFORM_H_
#include "libplatform/libplatform-export.h"
#include "libplatform/v8-tracing.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace platform {
enum class IdleTaskSupport { kDisabled, kEnabled };
enum class InProcessStackDumping { kDisabled, kEnabled };
enum class MessageLoopBehavior : bool {
kDoNotWait = false,
kWaitForWork = true
};
/**
* Returns a new instance of the default v8::Platform implementation.
*
* The caller will take ownership of the returned pointer. |thread_pool_size|
* is the number of worker threads to allocate for background jobs. If a value
* of zero is passed, a suitable default based on the current number of
* processors online will be chosen.
* If |idle_task_support| is enabled then the platform will accept idle
* tasks (IdleTasksEnabled will return true) and will rely on the embedder
* calling v8::platform::RunIdleTasks to process the idle tasks.
*/
V8_PLATFORM_EXPORT v8::Platform* CreateDefaultPlatform(
int thread_pool_size = 0,
IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
InProcessStackDumping in_process_stack_dumping =
InProcessStackDumping::kEnabled);
/**
* Pumps the message loop for the given isolate.
*
* 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
* through the |behavior| parameter, this call does not block if no task is
* pending. The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT bool PumpMessageLoop(
v8::Platform* platform, v8::Isolate* isolate,
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.
*
* 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
* created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
v8::Isolate* isolate,
double idle_time_in_seconds);
/**
* Attempts to set the tracing controller for the given platform.
*
* The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void SetTracingController(
v8::Platform* platform,
v8::platform::tracing::TracingController* tracing_controller);
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_LIBPLATFORM_H_

View File

@ -0,0 +1,270 @@
// Copyright 2016 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_LIBPLATFORM_V8_TRACING_H_
#define V8_LIBPLATFORM_V8_TRACING_H_
#include <fstream>
#include <memory>
#include <unordered_set>
#include <vector>
#include "libplatform/libplatform-export.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace base {
class Mutex;
} // namespace base
namespace platform {
namespace tracing {
const int kTraceMaxNumArgs = 2;
class V8_PLATFORM_EXPORT TraceObject {
public:
union ArgValue {
bool as_bool;
uint64_t as_uint;
int64_t as_int;
double as_double;
const void* as_pointer;
const char* as_string;
};
TraceObject() {}
~TraceObject();
void Initialize(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateDuration();
void InitializeForTesting(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
uint64_t duration, uint64_t cpu_duration);
int pid() const { return pid_; }
int tid() const { return tid_; }
char phase() const { return phase_; }
const uint8_t* category_enabled_flag() const {
return category_enabled_flag_;
}
const char* name() const { return name_; }
const char* scope() const { return scope_; }
uint64_t id() const { return id_; }
uint64_t bind_id() const { return bind_id_; }
int num_args() const { return num_args_; }
const char** arg_names() { return arg_names_; }
uint8_t* arg_types() { return arg_types_; }
ArgValue* arg_values() { return arg_values_; }
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables() {
return arg_convertables_;
}
unsigned int flags() const { return flags_; }
int64_t ts() { return ts_; }
int64_t tts() { return tts_; }
uint64_t duration() { return duration_; }
uint64_t cpu_duration() { return cpu_duration_; }
private:
int pid_;
int tid_;
char phase_;
const char* name_;
const char* scope_;
const uint8_t* category_enabled_flag_;
uint64_t id_;
uint64_t bind_id_;
int num_args_ = 0;
const char* arg_names_[kTraceMaxNumArgs];
uint8_t arg_types_[kTraceMaxNumArgs];
ArgValue arg_values_[kTraceMaxNumArgs];
std::unique_ptr<v8::ConvertableToTraceFormat>
arg_convertables_[kTraceMaxNumArgs];
char* parameter_copy_storage_ = nullptr;
unsigned int flags_;
int64_t ts_;
int64_t tts_;
uint64_t duration_;
uint64_t cpu_duration_;
// Disallow copy and assign
TraceObject(const TraceObject&) = delete;
void operator=(const TraceObject&) = delete;
};
class V8_PLATFORM_EXPORT TraceWriter {
public:
TraceWriter() {}
virtual ~TraceWriter() {}
virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
virtual void Flush() = 0;
static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
private:
// Disallow copy and assign
TraceWriter(const TraceWriter&) = delete;
void operator=(const TraceWriter&) = delete;
};
class V8_PLATFORM_EXPORT TraceBufferChunk {
public:
explicit TraceBufferChunk(uint32_t seq);
void Reset(uint32_t new_seq);
bool IsFull() const { return next_free_ == kChunkSize; }
TraceObject* AddTraceEvent(size_t* event_index);
TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
uint32_t seq() const { return seq_; }
size_t size() const { return next_free_; }
static const size_t kChunkSize = 64;
private:
size_t next_free_ = 0;
TraceObject chunk_[kChunkSize];
uint32_t seq_;
// Disallow copy and assign
TraceBufferChunk(const TraceBufferChunk&) = delete;
void operator=(const TraceBufferChunk&) = delete;
};
class V8_PLATFORM_EXPORT TraceBuffer {
public:
TraceBuffer() {}
virtual ~TraceBuffer() {}
virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
virtual bool Flush() = 0;
static const size_t kRingBufferChunks = 1024;
static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
TraceWriter* trace_writer);
private:
// Disallow copy and assign
TraceBuffer(const TraceBuffer&) = delete;
void operator=(const TraceBuffer&) = delete;
};
// Options determines how the trace buffer stores data.
enum TraceRecordMode {
// Record until the trace buffer is full.
RECORD_UNTIL_FULL,
// Record until the user ends the trace. The trace buffer is a fixed size
// and we use it as a ring buffer during recording.
RECORD_CONTINUOUSLY,
// Record until the trace buffer is full, but with a huge buffer size.
RECORD_AS_MUCH_AS_POSSIBLE,
// Echo to console. Events are discarded.
ECHO_TO_CONSOLE,
};
class V8_PLATFORM_EXPORT TraceConfig {
public:
typedef std::vector<std::string> StringList;
static TraceConfig* CreateDefaultTraceConfig();
TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
bool IsSystraceEnabled() const { return enable_systrace_; }
bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
void EnableSystrace() { enable_systrace_ = true; }
void EnableArgumentFilter() { enable_argument_filter_ = true; }
void AddIncludedCategory(const char* included_category);
bool IsCategoryGroupEnabled(const char* category_group) const;
private:
TraceRecordMode record_mode_;
bool enable_systrace_ : 1;
bool enable_argument_filter_ : 1;
StringList included_categories_;
// Disallow copy and assign
TraceConfig(const TraceConfig&) = delete;
void operator=(const TraceConfig&) = delete;
};
class V8_PLATFORM_EXPORT TracingController {
public:
enum Mode { DISABLED = 0, RECORDING_MODE };
// The pointer returned from GetCategoryGroupEnabledInternal() 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 {
// Category group enabled for the recording mode.
ENABLED_FOR_RECORDING = 1 << 0,
// Category group enabled by SetEventCallbackEnabled().
ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
// Category group enabled to export events to ETW.
ENABLED_FOR_ETW_EXPORT = 1 << 3
};
TracingController();
~TracingController();
void Initialize(TraceBuffer* trace_buffer);
const uint8_t* GetCategoryGroupEnabled(const char* category_group);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle);
void StartTracing(TraceConfig* trace_config);
void StopTracing();
void AddTraceStateObserver(Platform::TraceStateObserver* observer);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
void UpdateCategoryGroupEnabledFlag(size_t category_index);
void UpdateCategoryGroupEnabledFlags();
std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_;
Mode mode_ = DISABLED;
// Disallow copy and assign
TracingController(const TracingController&) = delete;
void operator=(const TracingController&) = delete;
};
} // namespace tracing
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_V8_TRACING_H_

View File

@ -0,0 +1,255 @@
// 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

@ -0,0 +1,13 @@
// Copyright 2016 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_INSPECTOR_PROTOCOL_H_
#define V8_V8_INSPECTOR_PROTOCOL_H_
#include "inspector/Debugger.h" // NOLINT(build/include)
#include "inspector/Runtime.h" // NOLINT(build/include)
#include "inspector/Schema.h" // NOLINT(build/include)
#include "v8-inspector.h" // NOLINT(build/include)
#endif // V8_V8_INSPECTOR_PROTOCOL_H_

View File

@ -0,0 +1,267 @@
// Copyright 2016 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_INSPECTOR_H_
#define V8_V8_INSPECTOR_H_
#include <stdint.h>
#include <cctype>
#include <memory>
#include "v8.h" // NOLINT(build/include)
namespace v8_inspector {
namespace protocol {
namespace Debugger {
namespace API {
class SearchMatch;
}
}
namespace Runtime {
namespace API {
class RemoteObject;
class StackTrace;
}
}
namespace Schema {
namespace API {
class Domain;
}
}
} // namespace protocol
class V8_EXPORT StringView {
public:
StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {}
StringView(const uint8_t* characters, size_t length)
: m_is8Bit(true), m_length(length), m_characters8(characters) {}
StringView(const uint16_t* characters, size_t length)
: m_is8Bit(false), m_length(length), m_characters16(characters) {}
bool is8Bit() const { return m_is8Bit; }
size_t length() const { return m_length; }
// TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used
// here.
const uint8_t* characters8() const { return m_characters8; }
const uint16_t* characters16() const { return m_characters16; }
private:
bool m_is8Bit;
size_t m_length;
union {
const uint8_t* m_characters8;
const uint16_t* m_characters16;
};
};
class V8_EXPORT StringBuffer {
public:
virtual ~StringBuffer() {}
virtual const StringView& string() = 0;
// This method copies contents.
static std::unique_ptr<StringBuffer> create(const StringView&);
};
class V8_EXPORT V8ContextInfo {
public:
V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId,
const StringView& humanReadableName)
: context(context),
contextGroupId(contextGroupId),
humanReadableName(humanReadableName),
hasMemoryOnConsole(false) {}
v8::Local<v8::Context> context;
// Each v8::Context is a part of a group. The group id must be non-zero.
int contextGroupId;
StringView humanReadableName;
StringView origin;
StringView auxData;
bool hasMemoryOnConsole;
static int executionContextId(v8::Local<v8::Context> context);
private:
// Disallow copying and allocating this one.
enum NotNullTagEnum { NotNullLiteral };
void* operator new(size_t) = delete;
void* operator new(size_t, NotNullTagEnum, void*) = delete;
void* operator new(size_t, void*) = delete;
V8ContextInfo(const V8ContextInfo&) = delete;
V8ContextInfo& operator=(const V8ContextInfo&) = delete;
};
class V8_EXPORT V8StackTrace {
public:
virtual bool isEmpty() const = 0;
virtual StringView topSourceURL() const = 0;
virtual int topLineNumber() const = 0;
virtual int topColumnNumber() const = 0;
virtual StringView topScriptId() const = 0;
virtual StringView topFunctionName() const = 0;
virtual ~V8StackTrace() {}
virtual std::unique_ptr<protocol::Runtime::API::StackTrace>
buildInspectorObject() const = 0;
virtual std::unique_ptr<StringBuffer> toString() const = 0;
// Safe to pass between threads, drops async chain.
virtual std::unique_ptr<V8StackTrace> clone() = 0;
};
class V8_EXPORT V8InspectorSession {
public:
virtual ~V8InspectorSession() {}
// Cross-context inspectable values (DOM nodes in different worlds, etc.).
class V8_EXPORT Inspectable {
public:
virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0;
virtual ~Inspectable() {}
};
virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0;
// Dispatching protocol messages.
static bool canDispatchMethod(const StringView& method);
virtual void dispatchProtocolMessage(const StringView& message) = 0;
virtual std::unique_ptr<StringBuffer> stateJSON() = 0;
virtual std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
supportedDomains() = 0;
// Debugger actions.
virtual void schedulePauseOnNextStatement(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void cancelPauseOnNextStatement() = 0;
virtual void breakProgram(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void setSkipAllPauses(bool) = 0;
virtual void resume() = 0;
virtual void stepOver() = 0;
virtual std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
searchInTextByLines(const StringView& text, const StringView& query,
bool caseSensitive, bool isRegex) = 0;
// Remote objects.
virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject(
v8::Local<v8::Context>, v8::Local<v8::Value>,
const StringView& groupName) = 0;
virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error,
const StringView& objectId, v8::Local<v8::Value>*,
v8::Local<v8::Context>*,
std::unique_ptr<StringBuffer>* objectGroup) = 0;
virtual void releaseObjectGroup(const StringView&) = 0;
};
class V8_EXPORT V8InspectorClient {
public:
virtual ~V8InspectorClient() {}
virtual void runMessageLoopOnPause(int contextGroupId) {}
virtual void quitMessageLoopOnPause() {}
virtual void runIfWaitingForDebugger(int contextGroupId) {}
virtual void muteMetrics(int contextGroupId) {}
virtual void unmuteMetrics(int contextGroupId) {}
virtual void beginUserGesture() {}
virtual void endUserGesture() {}
virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) {
return nullptr;
}
virtual bool formatAccessorsAsProperties(v8::Local<v8::Value>) {
return false;
}
virtual bool isInspectableHeapObject(v8::Local<v8::Object>) { return true; }
virtual v8::Local<v8::Context> ensureDefaultContextInGroup(
int contextGroupId) {
return v8::Local<v8::Context>();
}
virtual void beginEnsureAllContextsInGroup(int contextGroupId) {}
virtual void endEnsureAllContextsInGroup(int contextGroupId) {}
virtual void installAdditionalCommandLineAPI(v8::Local<v8::Context>,
v8::Local<v8::Object>) {}
virtual void consoleAPIMessage(int contextGroupId,
v8::Isolate::MessageErrorLevel level,
const StringView& message,
const StringView& url, unsigned lineNumber,
unsigned columnNumber, V8StackTrace*) {}
virtual v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*,
v8::Local<v8::Context>) {
return v8::MaybeLocal<v8::Value>();
}
virtual void consoleTime(const StringView& title) {}
virtual void consoleTimeEnd(const StringView& title) {}
virtual void consoleTimeStamp(const StringView& title) {}
virtual void consoleClear(int contextGroupId) {}
virtual double currentTimeMS() { return 0; }
typedef void (*TimerCallback)(void*);
virtual void startRepeatingTimer(double, TimerCallback, void* data) {}
virtual void cancelTimer(void* data) {}
// TODO(dgozman): this was added to support service worker shadow page. We
// should not connect at all.
virtual bool canExecuteScripts(int contextGroupId) { return true; }
};
class V8_EXPORT V8Inspector {
public:
static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*);
virtual ~V8Inspector() {}
// Contexts instrumentation.
virtual void contextCreated(const V8ContextInfo&) = 0;
virtual void contextDestroyed(v8::Local<v8::Context>) = 0;
virtual void resetContextGroup(int contextGroupId) = 0;
// Various instrumentation.
virtual void idleStarted() = 0;
virtual void idleFinished() = 0;
// Async stack traces instrumentation.
virtual void asyncTaskScheduled(const StringView& taskName, void* task,
bool recurring) = 0;
virtual void asyncTaskCanceled(void* task) = 0;
virtual void asyncTaskStarted(void* task) = 0;
virtual void asyncTaskFinished(void* task) = 0;
virtual void allAsyncTasksCanceled() = 0;
// Exceptions instrumentation.
virtual unsigned exceptionThrown(
v8::Local<v8::Context>, const StringView& message,
v8::Local<v8::Value> exception, const StringView& detailedMessage,
const StringView& url, unsigned lineNumber, unsigned columnNumber,
std::unique_ptr<V8StackTrace>, int scriptId) = 0;
virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId,
const StringView& message) = 0;
// Connection.
class V8_EXPORT Channel {
public:
virtual ~Channel() {}
virtual void sendResponse(int callId,
std::unique_ptr<StringBuffer> message) = 0;
virtual void sendNotification(std::unique_ptr<StringBuffer> message) = 0;
virtual void flushProtocolNotifications() = 0;
};
virtual std::unique_ptr<V8InspectorSession> connect(
int contextGroupId, Channel*, const StringView& state) = 0;
// API methods.
virtual std::unique_ptr<V8StackTrace> createStackTrace(
v8::Local<v8::StackTrace>) = 0;
virtual std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) = 0;
};
} // namespace v8_inspector
#endif // V8_V8_INSPECTOR_H_

View File

@ -0,0 +1,227 @@
// Copyright 2013 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_PLATFORM_H_
#define V8_V8_PLATFORM_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
namespace v8 {
class Isolate;
/**
* A Task represents a unit of work.
*/
class Task {
public:
virtual ~Task() = default;
virtual void Run() = 0;
};
/**
* An IdleTask represents a unit of work to be performed in idle time.
* The Run method is invoked with an argument that specifies the deadline in
* seconds returned by MonotonicallyIncreasingTime().
* The idle task is expected to complete by this deadline.
*/
class IdleTask {
public:
virtual ~IdleTask() = default;
virtual void Run(double deadline_in_seconds) = 0;
};
/**
* The interface represents complex arguments to trace events.
*/
class ConvertableToTraceFormat {
public:
virtual ~ConvertableToTraceFormat() = default;
/**
* Append the class info to the provided |out| string. The appended
* data must be a valid JSON object. Strings must be properly quoted, and
* escaped. There is no processing applied to the content after it is
* appended.
*/
virtual void AppendAsTraceFormat(std::string* out) const = 0;
};
/**
* V8 Platform abstraction layer.
*
* The embedder has to provide an implementation of this interface before
* initializing the rest of V8.
*/
class Platform {
public:
/**
* 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.
* The name parameter is a category group for example:
* TRACE_EVENT0("v8,parse", "V8.Parse")
* The pointer returned points to a value with zero or more of the bits
* defined in CategoryGroupEnabledFlags.
**/
virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
static uint8_t no = 0;
return &no;
}
/**
* Gets the category group name of the given category_enabled_flag pointer.
* 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
* tracing and the category of the particular trace are enabled. It is not
* advisable to call this function on its own; it is really only meant to be
* used by the trace macros. The returned handle can be used by
* UpdateTraceEventDuration to update the duration of COMPLETE events.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values, 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.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) {
return AddTraceEvent(phase, category_enabled_flag, name, scope, id, bind_id,
num_args, arg_names, arg_types, arg_values, flags);
}
/**
* Sets the duration field of a COMPLETE trace event. It must be called with
* the handle returned from AddTraceEvent().
**/
virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {}
class TraceStateObserver {
public:
virtual ~TraceStateObserver() = default;
virtual void OnTraceEnabled() = 0;
virtual void OnTraceDisabled() = 0;
};
/** Adds tracing state change observer. */
virtual void AddTraceStateObserver(TraceStateObserver*) {}
/** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
typedef void (*StackTracePrinter)();
/**
* Returns a function pointer that print a stack trace of the current stack
* on invocation. Disables printing of the stack trace if nullptr.
*/
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
};
} // namespace v8
#endif // V8_V8_PLATFORM_H_

View File

@ -0,0 +1,912 @@
// Copyright 2010 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_PROFILER_H_
#define V8_V8_PROFILER_H_
#include <unordered_set>
#include <vector>
#include "v8.h" // NOLINT(build/include)
/**
* Profiler support for the V8 JavaScript engine.
*/
namespace v8 {
class HeapGraphNode;
struct HeapStatsUpdate;
typedef uint32_t SnapshotObjectId;
struct CpuProfileDeoptFrame {
int script_id;
size_t position;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
#endif
namespace v8 {
struct V8_EXPORT CpuProfileDeoptInfo {
/** A pointer to a static string owned by v8. */
const char* deopt_reason;
std::vector<CpuProfileDeoptFrame> stack;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
#endif
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.
struct TickSample {
// Internal profiling (with --prof + tools/$OS-tick-processor) wants to
// include the runtime function we're calling. Externally exposed tick
// samples don't care.
enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
TickSample()
: state(OTHER),
pc(nullptr),
external_callback_entry(nullptr),
frames_count(0),
has_external_callback(false),
update_stats(true) {}
/**
* Initialize a tick sample from the isolate.
* \param isolate The isolate.
* \param state Execution state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param update_stats Whether update the sample to the aggregated stats.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
*/
void Init(Isolate* isolate, const v8::RegisterState& state,
RecordCEntryFrame record_c_entry_frame, bool update_stats,
bool use_simulator_reg_state = true);
/**
* Get a call stack sample from the isolate.
* \param isolate The isolate.
* \param state Register state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param frames Caller allocated buffer to store stack frames.
* \param frames_limit Maximum number of frames to capture. The buffer must
* be large enough to hold the number of frames.
* \param sample_info The sample info is filled up by the function
* provides number of actual captured stack frames and
* the current VM state.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
* \note GetStackSample is thread and signal safe and should only be called
* when the JS thread is paused or interrupted.
* Otherwise the behavior is undefined.
*/
static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
RecordCEntryFrame record_c_entry_frame,
void** frames, size_t frames_limit,
v8::SampleInfo* sample_info,
bool use_simulator_reg_state = true);
StateTag state; // The state of the VM.
void* pc; // Instruction pointer.
union {
void* tos; // Top stack value (*sp).
void* external_callback_entry;
};
static const unsigned kMaxFramesCountLog2 = 8;
static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
void* stack[kMaxFramesCount]; // Call stack.
unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
bool has_external_callback : 1;
bool update_stats : 1; // Whether the sample should update aggregated stats.
};
/**
* CpuProfileNode represents a node in a call graph.
*/
class V8_EXPORT CpuProfileNode {
public:
struct LineTick {
/** The 1-based number of the source line where the function originates. */
int line;
/** The count of samples associated with the source line. */
unsigned int hit_count;
};
/** Returns function name (empty string for anonymous functions.) */
Local<String> GetFunctionName() const;
/**
* Returns function name (empty string for anonymous functions.)
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetFunctionNameStr() const;
/** Returns id of the script where function is located. */
int GetScriptId() const;
/** Returns resource name for script from where the function originates. */
Local<String> GetScriptResourceName() const;
/**
* Returns resource name for script from where the function originates.
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetScriptResourceNameStr() const;
/**
* Returns the number, 1-based, of the line where the function originates.
* kNoLineNumberInfo if no line number information is available.
*/
int GetLineNumber() const;
/**
* Returns 1-based number of the column where the function originates.
* kNoColumnNumberInfo if no column number information is available.
*/
int GetColumnNumber() const;
/**
* Returns the number of the function's source lines that collect the samples.
*/
unsigned int GetHitLineCount() const;
/** Returns the set of source lines that collect the samples.
* The caller allocates buffer and responsible for releasing it.
* True if all available entries are copied, otherwise false.
* The function copies nothing if buffer is not large enough.
*/
bool GetLineTicks(LineTick* entries, unsigned int length) const;
/** Returns bailout reason for the function
* if the optimization was disabled for it.
*/
const char* GetBailoutReason() const;
/**
* Returns the count of samples where the function was currently executing.
*/
unsigned GetHitCount() const;
/** Returns function entry UID. */
V8_DEPRECATE_SOON(
"Use GetScriptId, GetLineNumber, and GetColumnNumber instead.",
unsigned GetCallUid() const);
/** Returns id of the node. The id is unique within the tree */
unsigned GetNodeId() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child node by index. */
const CpuProfileNode* GetChild(int index) const;
/** Retrieves deopt infos for the node. */
const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* CpuProfile contains a CPU profile in a form of top-down call tree
* (from main() down to functions that do all the work).
*/
class V8_EXPORT CpuProfile {
public:
/** Returns CPU profile title. */
Local<String> GetTitle() const;
/** Returns the root node of the top down call tree. */
const CpuProfileNode* GetTopDownRoot() const;
/**
* Returns number of samples recorded. The samples are not recorded unless
* |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
*/
int GetSamplesCount() const;
/**
* Returns profile node corresponding to the top frame the sample at
* the given index.
*/
const CpuProfileNode* GetSample(int index) const;
/**
* Returns the timestamp of the sample. The timestamp is the number of
* microseconds since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetSampleTimestamp(int index) const;
/**
* Returns time when the profile recording was started (in microseconds)
* since some unspecified starting point.
*/
int64_t GetStartTime() const;
/**
* Returns time when the profile recording was stopped (in microseconds)
* since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetEndTime() const;
/**
* Deletes the profile and removes it from CpuProfiler's list.
* All pointers to nodes previously returned become invalid.
*/
void Delete();
};
/**
* Interface for controlling CPU profiling. Instance of the
* profiler can be created using v8::CpuProfiler::New method.
*/
class V8_EXPORT CpuProfiler {
public:
/**
* Creates a new CPU profiler for the |isolate|. The isolate must be
* initialized. The profiler object must be disposed after use by calling
* |Dispose| method.
*/
static CpuProfiler* New(Isolate* isolate);
/**
* Disposes the CPU profiler object.
*/
void Dispose();
/**
* Changes default CPU profiler sampling interval to the specified number
* of microseconds. Default interval is 1000us. This method must be called
* when there are no profiles being recorded.
*/
void SetSamplingInterval(int us);
/**
* Starts collecting CPU profile. Title may be an empty string. It
* is allowed to have several profiles being collected at
* once. Attempts to start collecting several profiles with the same
* title are silently ignored. While collecting a profile, functions
* from all security contexts are included in it. The token-based
* filtering is only performed when querying for a profile.
*
* |record_samples| parameter controls whether individual samples should
* be recorded in addition to the aggregated tree.
*/
void StartProfiling(Local<String> title, bool record_samples = false);
/**
* Stops collecting CPU profile with a given title and returns it.
* If the title given is empty, finishes the last profile started.
*/
CpuProfile* StopProfiling(Local<String> title);
/**
* Force collection of a sample. Must be called on the VM thread.
* Recording the forced sample does not contribute to the aggregated
* profile statistics.
*/
void CollectSample();
/**
* Tells the profiler whether the embedder is idle.
*/
void SetIdle(bool is_idle);
private:
CpuProfiler();
~CpuProfiler();
CpuProfiler(const CpuProfiler&);
CpuProfiler& operator=(const CpuProfiler&);
};
/**
* HeapSnapshotEdge represents a directed connection between heap
* graph nodes: from retainers to retained nodes.
*/
class V8_EXPORT HeapGraphEdge {
public:
enum Type {
kContextVariable = 0, // A variable from a function context.
kElement = 1, // An element of an array.
kProperty = 2, // A named object property.
kInternal = 3, // A link that can't be accessed from JS,
// thus, its name isn't a real property name
// (e.g. parts of a ConsString).
kHidden = 4, // A link that is needed for proper sizes
// calculation, but may be hidden from user.
kShortcut = 5, // A link that must not be followed during
// sizes calculation.
kWeak = 6 // A weak reference (ignored by the GC).
};
/** Returns edge type (see HeapGraphEdge::Type). */
Type GetType() const;
/**
* Returns edge name. This can be a variable name, an element index, or
* a property name.
*/
Local<Value> GetName() const;
/** Returns origin node. */
const HeapGraphNode* GetFromNode() const;
/** Returns destination node. */
const HeapGraphNode* GetToNode() const;
};
/**
* HeapGraphNode represents a node in a heap graph.
*/
class V8_EXPORT HeapGraphNode {
public:
enum Type {
kHidden = 0, // Hidden node, may be filtered when shown to user.
kArray = 1, // An array of elements.
kString = 2, // A string.
kObject = 3, // A JS object (except for arrays and strings).
kCode = 4, // Compiled code.
kClosure = 5, // Function closure.
kRegExp = 6, // RegExp.
kHeapNumber = 7, // Number stored in the heap.
kNative = 8, // Native object (not from V8 heap).
kSynthetic = 9, // Synthetic object, usualy used for grouping
// snapshot items together.
kConsString = 10, // Concatenated string. A pair of pointers to strings.
kSlicedString = 11, // Sliced string. A fragment of another string.
kSymbol = 12 // A Symbol (ES6).
};
/** Returns node type (see HeapGraphNode::Type). */
Type GetType() const;
/**
* Returns node name. Depending on node's type this can be the name
* of the constructor (for objects), the name of the function (for
* closures), string value, or an empty string (for compiled code).
*/
Local<String> GetName() const;
/**
* Returns node id. For the same heap object, the id remains the same
* across all snapshots.
*/
SnapshotObjectId GetId() const;
/** Returns node's own size, in bytes. */
size_t GetShallowSize() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child by index. */
const HeapGraphEdge* GetChild(int index) const;
};
/**
* An interface for exporting data from V8, using "push" model.
*/
class V8_EXPORT OutputStream { // NOLINT
public:
enum WriteResult {
kContinue = 0,
kAbort = 1
};
virtual ~OutputStream() {}
/** Notify about the end of stream. */
virtual void EndOfStream() = 0;
/** Get preferred output chunk size. Called only once. */
virtual int GetChunkSize() { return 1024; }
/**
* Writes the next chunk of snapshot data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
/**
* Writes the next chunk of heap stats data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
return kAbort;
}
};
/**
* HeapSnapshots record the state of the JS heap at some moment.
*/
class V8_EXPORT HeapSnapshot {
public:
enum SerializationFormat {
kJSON = 0 // See format description near 'Serialize' method.
};
/** Returns the root node of the heap graph. */
const HeapGraphNode* GetRoot() const;
/** Returns a node by its id. */
const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
/** Returns total nodes count in the snapshot. */
int GetNodesCount() const;
/** Returns a node by index. */
const HeapGraphNode* GetNode(int index) const;
/** Returns a max seen JS object Id. */
SnapshotObjectId GetMaxSnapshotJSObjectId() const;
/**
* Deletes the snapshot and removes it from HeapProfiler's list.
* All pointers to nodes, edges and paths previously returned become
* invalid.
*/
void Delete();
/**
* Prepare a serialized representation of the snapshot. The result
* is written into the stream provided in chunks of specified size.
* The total length of the serialized snapshot is unknown in
* advance, it can be roughly equal to JS heap size (that means,
* it can be really big - tens of megabytes).
*
* For the JSON format, heap contents are represented as an object
* with the following structure:
*
* {
* snapshot: {
* title: "...",
* uid: nnn,
* meta: { meta-info },
* node_count: nnn,
* edge_count: nnn
* },
* nodes: [nodes array],
* edges: [edges array],
* strings: [strings array]
* }
*
* Nodes reference strings, other nodes, and edges by their indexes
* in corresponding arrays.
*/
void Serialize(OutputStream* stream,
SerializationFormat format = kJSON) const;
};
/**
* An interface for reporting progress and controlling long-running
* activities.
*/
class V8_EXPORT ActivityControl { // NOLINT
public:
enum ControlOption {
kContinue = 0,
kAbort = 1
};
virtual ~ActivityControl() {}
/**
* Notify about current progress. The activity can be stopped by
* returning kAbort as the callback result.
*/
virtual ControlOption ReportProgressValue(int done, int total) = 0;
};
/**
* AllocationProfile is a sampled profile of allocations done by the program.
* This is structured as a call-graph.
*/
class V8_EXPORT AllocationProfile {
public:
struct Allocation {
/**
* Size of the sampled allocation object.
*/
size_t size;
/**
* The number of objects of such size that were sampled.
*/
unsigned int count;
};
/**
* Represents a node in the call-graph.
*/
struct Node {
/**
* Name of the function. May be empty for anonymous functions or if the
* script corresponding to this function has been unloaded.
*/
Local<String> name;
/**
* Name of the script containing the function. May be empty if the script
* name is not available, or if the script has been unloaded.
*/
Local<String> script_name;
/**
* id of the script where the function is located. May be equal to
* v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.
*/
int script_id;
/**
* Start position of the function in the script.
*/
int start_position;
/**
* 1-indexed line number where the function starts. May be
* kNoLineNumberInfo if no line number information is available.
*/
int line_number;
/**
* 1-indexed column number where the function starts. May be
* kNoColumnNumberInfo if no line number information is available.
*/
int column_number;
/**
* List of callees called from this node for which we have sampled
* allocations. The lifetime of the children is scoped to the containing
* AllocationProfile.
*/
std::vector<Node*> children;
/**
* List of self allocations done by this node in the call-graph.
*/
std::vector<Allocation> allocations;
};
/**
* 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
* containing AllocationProfile.
*/
virtual Node* GetRootNode() = 0;
virtual ~AllocationProfile() {}
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* Interface for controlling heap profiling. Instance of the
* profiler can be retrieved using v8::Isolate::GetHeapProfiler.
*/
class V8_EXPORT HeapProfiler {
public:
enum SamplingFlags {
kSamplingNoFlags = 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.
*/
typedef RetainerInfos (*GetRetainerInfosCallback)(v8::Isolate* isolate);
/**
* 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. */
int GetSnapshotCount();
/** Returns a snapshot by index. */
const HeapSnapshot* GetHeapSnapshot(int index);
/**
* Returns SnapshotObjectId for a heap object referenced by |value| if
* it has been seen by the heap profiler, kUnknownObjectId otherwise.
*/
SnapshotObjectId GetObjectId(Local<Value> value);
/**
* Returns heap object with given SnapshotObjectId if the object is alive,
* otherwise empty handle is returned.
*/
Local<Value> FindObjectById(SnapshotObjectId id);
/**
* Clears internal map from SnapshotObjectId to heap object. The new objects
* will not be added into it unless a heap snapshot is taken or heap object
* tracking is kicked off.
*/
void ClearObjectIds();
/**
* A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
* it in case heap profiler cannot find id for the object passed as
* parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
*/
static const SnapshotObjectId kUnknownObjectId = 0;
/**
* Callback interface for retrieving user friendly names of global objects.
*/
class ObjectNameResolver {
public:
/**
* Returns name to be used in the heap snapshot for given node. Returned
* string must stay alive until snapshot collection is completed.
*/
virtual const char* GetName(Local<Object> object) = 0;
protected:
virtual ~ObjectNameResolver() {}
};
/**
* Takes a heap snapshot and returns it.
*/
const HeapSnapshot* TakeHeapSnapshot(
ActivityControl* control = NULL,
ObjectNameResolver* global_object_name_resolver = NULL);
/**
* Starts tracking of heap objects population statistics. After calling
* this method, all heap objects relocations done by the garbage collector
* are being registered.
*
* |track_allocations| parameter controls whether stack trace of each
* allocation in the heap will be recorded and reported as part of
* HeapSnapshot.
*/
void StartTrackingHeapObjects(bool track_allocations = false);
/**
* Adds a new time interval entry to the aggregated statistics array. The
* time interval entry contains information on the current heap objects
* population size. The method also updates aggregated statistics and
* reports updates for all previous time intervals via the OutputStream
* object. Updates on each time interval are provided as a stream of the
* HeapStatsUpdate structure instances.
* If |timestamp_us| is supplied, timestamp of the new entry will be written
* into it. The return value of the function is the last seen heap object Id.
*
* StartTrackingHeapObjects must be called before the first call to this
* method.
*/
SnapshotObjectId GetHeapStats(OutputStream* stream,
int64_t* timestamp_us = NULL);
/**
* Stops tracking of heap objects population statistics, cleans up all
* collected data. StartHeapObjectsTracking must be called again prior to
* calling GetHeapStats next time.
*/
void StopTrackingHeapObjects();
/**
* Starts gathering a sampling heap profile. A sampling heap profile is
* similar to tcmalloc's heap profiler and Go's mprof. It samples object
* allocations and builds an online 'sampling' heap profile. At any point in
* time, this profile is expected to be a representative sample of objects
* currently live in the system. Each sampled allocation includes the stack
* trace at the time of allocation, which makes this really useful for memory
* leak detection.
*
* This mechanism is intended to be cheap enough that it can be used in
* production with minimal performance overhead.
*
* Allocations are sampled using a randomized Poisson process. On average, one
* allocation will be sampled every |sample_interval| bytes allocated. The
* |stack_depth| parameter controls the maximum number of stack frames to be
* captured on each allocation.
*
* NOTE: This is a proof-of-concept at this point. Right now we only sample
* newspace allocations. Support for paged space allocation (e.g. pre-tenured
* objects, large objects, code objects, etc.) and native allocations
* doesn't exist yet, but is anticipated in the future.
*
* Objects allocated before the sampling is started will not be included in
* the profile.
*
* Returns false if a sampling heap profiler is already running.
*/
bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
int stack_depth = 16,
SamplingFlags flags = kSamplingNoFlags);
/**
* Stops the sampling heap profile and discards the current profile.
*/
void StopSamplingHeapProfiler();
/**
* Returns the sampled profile of allocations allocated (and still live) since
* StartSamplingHeapProfiler was called. The ownership of the pointer is
* transfered to the caller. Returns nullptr if sampling heap profiler is not
* active.
*/
AllocationProfile* GetAllocationProfile();
/**
* Deletes all snapshots taken. All previously returned pointers to
* snapshots and their contents become invalid after this call.
*/
void DeleteAllHeapSnapshots();
/** Binds a callback to embedder's class ID. */
void SetWrapperClassInfoProvider(
uint16_t class_id,
WrapperInfoCallback callback);
void SetGetRetainerInfosCallback(GetRetainerInfosCallback callback);
/**
* Default value of persistent handle class ID. Must not be used to
* define a class. Can be used to reset a class of a persistent
* handle.
*/
static const uint16_t kPersistentHandleNoClassId = 0;
/** Returns memory used for profiler internal data and snapshots. */
size_t GetProfilerMemorySize();
private:
HeapProfiler();
~HeapProfiler();
HeapProfiler(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.
* See HeapProfiler::GetHeapStats.
*/
struct HeapStatsUpdate {
HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
: index(index), count(count), size(size) { }
uint32_t index; // Index of the time interval that was changed.
uint32_t count; // New value of count field for the interval with this index.
uint32_t size; // New value of size field for the interval with this index.
};
} // namespace v8
#endif // V8_V8_PROFILER_H_

View File

@ -0,0 +1,48 @@
// Copyright 2010 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_TEST_H_
#define V8_V8_TEST_H_
#include "v8.h" // NOLINT(build/include)
/**
* Testing support for the V8 JavaScript engine.
*/
namespace v8 {
class V8_EXPORT Testing {
public:
enum StressType {
kStressTypeOpt,
kStressTypeDeopt
};
/**
* Set the type of stressing to do. The default if not set is kStressTypeOpt.
*/
static void SetStressRunType(StressType type);
/**
* Get the number of runs of a given test that is required to get the full
* stress coverage.
*/
static int GetStressRuns();
/**
* Indicate the number of the run which is about to start. The value of run
* should be between 0 and one less than the result from GetStressRuns()
*/
static void PrepareStressRun(int run);
/**
* Force deoptimization of all functions.
*/
static void DeoptimizeAll(Isolate* isolate);
};
} // namespace v8
#endif // V8_V8_TEST_H_

View File

@ -0,0 +1,655 @@
// Copyright 2014 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_UTIL_H_
#define V8_UTIL_H_
#include "v8.h" // NOLINT(build/include)
#include <assert.h>
#include <map>
#include <vector>
/**
* Support for Persistent containers.
*
* C++11 embedders can use STL containers with Global values,
* but pre-C++11 does not support the required move semantic and hence
* may want these container classes.
*/
namespace v8 {
typedef uintptr_t PersistentContainerValue;
static const uintptr_t kPersistentContainerNotFound = 0;
enum PersistentContainerCallbackType {
kNotWeak,
// These correspond to v8::WeakCallbackType
kWeakWithParameter,
kWeakWithInternalFields,
kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
};
/**
* A default trait implemenation for PersistentValueMap which uses std::map
* as a backing map.
*
* Users will have to implement their own weak callbacks & dispose traits.
*/
template<typename K, typename V>
class StdMapTraits {
public:
// STL map & related:
typedef std::map<K, PersistentContainerValue> Impl;
typedef typename Impl::iterator Iterator;
static bool Empty(Impl* impl) { return impl->empty(); }
static size_t Size(Impl* impl) { return impl->size(); }
static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
static Iterator Begin(Impl* impl) { return impl->begin(); }
static Iterator End(Impl* impl) { return impl->end(); }
static K Key(Iterator it) { return it->first; }
static PersistentContainerValue Value(Iterator it) { return it->second; }
static PersistentContainerValue Set(Impl* impl, K key,
PersistentContainerValue value) {
std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
PersistentContainerValue old_value = kPersistentContainerNotFound;
if (!res.second) {
old_value = res.first->second;
res.first->second = value;
}
return old_value;
}
static PersistentContainerValue Get(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
return it->second;
}
static PersistentContainerValue Remove(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
PersistentContainerValue value = it->second;
impl->erase(it);
return value;
}
};
/**
* A default trait implementation for PersistentValueMap, which inherits
* a std:map backing map from StdMapTraits and holds non-weak persistent
* objects and has no special Dispose handling.
*
* You should not derive from this class, since MapType depends on the
* surrounding class, and hence a subclass cannot simply inherit the methods.
*/
template<typename K, typename V>
class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(
MapType* map, const K& key, Local<V> value) {
return NULL;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return NULL;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) { }
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
};
template <typename K, typename V>
class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
private:
template <typename T>
struct RemovePointer;
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
Local<V> value) {
return nullptr;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return nullptr;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) {}
static void OnWeakCallback(
const WeakCallbackInfo<WeakCallbackDataType>& data) {}
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
// This is a second pass callback, so SetSecondPassCallback cannot be called.
static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {}
private:
template <typename T>
struct RemovePointer<T*> {
typedef T Type;
};
};
/**
* A map wrapper that allows using Global as a mapped value.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* The map relies on a backing map, whose type and accessors are described
* by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template <typename K, typename V, typename Traits>
class PersistentValueMapBase {
public:
Isolate* GetIsolate() { return isolate_; }
/**
* Return size of the map.
*/
size_t Size() { return Traits::Size(&impl_); }
/**
* Return whether the map holds weak persistents.
*/
bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
/**
* Get value stored in map.
*/
Local<V> Get(const K& key) {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
}
/**
* Check whether a value is contained in the map.
*/
bool Contains(const K& key) {
return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
}
/**
* Get value stored in map and set it in returnValue.
* Return true if a value was found.
*/
bool SetReturnValue(const K& key,
ReturnValue<Value> returnValue) {
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
* key.
*/
void RegisterExternallyReferencedObject(K& key) {
assert(Contains(key));
V8::RegisterExternallyReferencedObject(
reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Isolate*>(GetIsolate()));
}
/**
* Return value for key and remove it from the map.
*/
Global<V> Remove(const K& key) {
return Release(Traits::Remove(&impl_, key)).Pass();
}
/**
* Traverses the map repeatedly,
* in case side effects of disposal cause insertions.
**/
void Clear() {
typedef typename Traits::Iterator It;
HandleScope handle_scope(isolate_);
// TODO(dcarney): figure out if this swap and loop is necessary.
while (!Traits::Empty(&impl_)) {
typename Traits::Impl impl;
Traits::Swap(impl_, impl);
for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
Traits::Key(i));
}
}
}
/**
* Helper class for GetReference/SetWithReference. Do not use outside
* that context.
*/
class PersistentValueReference {
public:
PersistentValueReference() : value_(kPersistentContainerNotFound) { }
PersistentValueReference(const PersistentValueReference& other)
: value_(other.value_) { }
Local<V> NewLocal(Isolate* isolate) const {
return Local<V>::New(isolate, FromVal(value_));
}
bool IsEmpty() const {
return value_ == kPersistentContainerNotFound;
}
template<typename T>
bool SetReturnValue(ReturnValue<T> returnValue) {
return SetReturnValueFromVal(&returnValue, value_);
}
void Reset() {
value_ = kPersistentContainerNotFound;
}
void operator=(const PersistentValueReference& other) {
value_ = other.value_;
}
private:
friend class PersistentValueMapBase;
friend class PersistentValueMap<K, V, Traits>;
friend class GlobalValueMap<K, V, Traits>;
explicit PersistentValueReference(PersistentContainerValue value)
: value_(value) { }
void operator=(PersistentContainerValue value) {
value_ = value;
}
PersistentContainerValue value_;
};
/**
* Get a reference to a map value. This enables fast, repeated access
* to a value stored in the map while the map remains unchanged.
*
* Careful: This is potentially unsafe, so please use with care.
* The value will become invalid if the value for this key changes
* in the underlying map, as a result of Set or Remove for the same
* key; as a result of the weak callback for the same key; or as a
* result of calling Clear() or destruction of the map.
*/
PersistentValueReference GetReference(const K& key) {
return PersistentValueReference(Traits::Get(&impl_, key));
}
protected:
explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
~PersistentValueMapBase() { Clear(); }
Isolate* isolate() { return isolate_; }
typename Traits::Impl* impl() { return &impl_; }
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static PersistentContainerValue Leak(Global<V>* persistent) {
return reinterpret_cast<PersistentContainerValue>(persistent->val_);
}
/**
* Return a container value as Global and make sure the weak
* callback is properly disposed of. All remove functionality should go
* through this.
*/
static Global<V> Release(PersistentContainerValue v) {
Global<V> p;
p.val_ = FromVal(v);
if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
Traits::DisposeCallbackData(
p.template ClearWeak<typename Traits::WeakCallbackDataType>());
}
return p.Pass();
}
void RemoveWeak(const K& key) {
Global<V> p;
p.val_ = FromVal(Traits::Remove(&impl_, key));
p.Reset();
}
private:
PersistentValueMapBase(PersistentValueMapBase&);
void operator=(PersistentValueMapBase&);
static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
PersistentContainerValue value) {
bool hasValue = value != kPersistentContainerNotFound;
if (hasValue) {
returnValue->SetInternal(
*reinterpret_cast<internal::Object**>(FromVal(value)));
}
return hasValue;
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
template <typename K, typename V, typename Traits>
class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit PersistentValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), WeakCallback);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void WeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
PersistentValueMap<K, V, Traits>* persistentValueMap =
Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
Traits::Dispose(data.GetIsolate(),
persistentValueMap->Remove(key).Pass(), key);
Traits::DisposeCallbackData(data.GetParameter());
}
}
};
template <typename K, typename V, typename Traits>
class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit GlobalValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
WeakCallbackType callback_type =
Traits::kCallbackType == kWeakWithInternalFields
? WeakCallbackType::kInternalFields
: WeakCallbackType::kParameter;
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
callback_type);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void OnWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
auto map = Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
map->RemoveWeak(key);
Traits::OnWeakCallback(data);
data.SetSecondPassCallback(SecondWeakCallback);
}
}
static void SecondWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
Traits::DisposeWeak(data);
}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Persistents are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template<typename K, typename V,
typename Traits = DefaultPersistentValueMapTraits<K, V> >
class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
public:
explicit StdPersistentValueMap(Isolate* isolate)
: PersistentValueMap<K, V, Traits>(isolate) {}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Globals are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template <typename K, typename V,
typename Traits = DefaultGlobalMapTraits<K, V> >
class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
public:
explicit StdGlobalValueMap(Isolate* isolate)
: GlobalValueMap<K, V, Traits>(isolate) {}
};
class DefaultPersistentValueVectorTraits {
public:
typedef std::vector<PersistentContainerValue> Impl;
static void Append(Impl* impl, PersistentContainerValue value) {
impl->push_back(value);
}
static bool IsEmpty(const Impl* impl) {
return impl->empty();
}
static size_t Size(const Impl* impl) {
return impl->size();
}
static PersistentContainerValue Get(const Impl* impl, size_t i) {
return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
}
static void ReserveCapacity(Impl* impl, size_t capacity) {
impl->reserve(capacity);
}
static void Clear(Impl* impl) {
impl->clear();
}
};
/**
* A vector wrapper that safely stores Global values.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* This class relies on a backing vector implementation, whose type and methods
* are described by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
class PersistentValueVector {
public:
explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
~PersistentValueVector() {
Clear();
}
/**
* Append a value to the vector.
*/
void Append(Local<V> value) {
Global<V> persistent(isolate_, value);
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Append a persistent's value to the vector.
*/
void Append(Global<V> persistent) {
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Are there any values in the vector?
*/
bool IsEmpty() const {
return Traits::IsEmpty(&impl_);
}
/**
* How many elements are in the vector?
*/
size_t Size() const {
return Traits::Size(&impl_);
}
/**
* Retrieve the i-th value in the vector.
*/
Local<V> Get(size_t index) const {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
}
/**
* Remove all elements from the vector.
*/
void Clear() {
size_t length = Traits::Size(&impl_);
for (size_t i = 0; i < length; i++) {
Global<V> p;
p.val_ = FromVal(Traits::Get(&impl_, i));
}
Traits::Clear(&impl_);
}
/**
* Reserve capacity in the vector.
* (Efficiency gains depend on the backing implementation.)
*/
void ReserveCapacity(size_t capacity) {
Traits::ReserveCapacity(&impl_, capacity);
}
private:
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
} // namespace v8
#endif // V8_UTIL_H

View File

@ -0,0 +1,24 @@
// Copyright 2017 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.
/**
* Compile-time constants.
*
* This header provides access to information about the value serializer at
* compile time, without declaring or defining any symbols that require linking
* to V8.
*/
#ifndef INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#define INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#include <stdint.h>
namespace v8 {
constexpr uint32_t CurrentValueSerializerFormatVersion() { return 13; }
} // namespace v8
#endif // INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_

View File

@ -0,0 +1,33 @@
// Copyright 2017 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_VERSION_STRING_H_
#define V8_VERSION_STRING_H_
#include "v8-version.h" // NOLINT(build/include)
// This is here rather than v8-version.h to keep that file simple and
// machine-processable.
#if V8_IS_CANDIDATE_VERSION
#define V8_CANDIDATE_STRING " (candidate)"
#else
#define V8_CANDIDATE_STRING ""
#endif
#define V8_SX(x) #x
#define V8_S(x) V8_SX(x)
#if V8_PATCH_LEVEL > 0
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \
V8_PATCH_LEVEL) V8_CANDIDATE_STRING
#else
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) V8_CANDIDATE_STRING
#endif
#endif // V8_VERSION_STRING_H_

View File

@ -0,0 +1,20 @@
// Copyright 2015 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_INCLUDE_VERSION_H_ // V8_VERSION_H_ conflicts with src/version.h
#define V8_INCLUDE_VERSION_H_
// These macros define the version number for the current version.
// 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.
#define V8_MAJOR_VERSION 6
#define V8_MINOR_VERSION 0
#define V8_BUILD_NUMBER 286
#define V8_PATCH_LEVEL 52
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define V8_IS_CANDIDATE_VERSION 0
#endif // V8_INCLUDE_VERSION_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,428 @@
// Copyright 2013 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 V8CONFIG_H_
#define V8CONFIG_H_
// clang-format off
// Platform headers for feature detection below.
#if defined(__ANDROID__)
# include <sys/cdefs.h>
#elif defined(__APPLE__)
# include <TargetConditionals.h>
#elif defined(__linux__)
# include <features.h>
#endif
// This macro allows to test for the version of the GNU C library (or
// a compatible C library that masquerades as glibc). It evaluates to
// 0 if libc is not GNU libc or compatible.
// Use like:
// #if V8_GLIBC_PREREQ(2, 3)
// ...
// #endif
#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
# define V8_GLIBC_PREREQ(major, minor) \
((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor)))
#else
# define V8_GLIBC_PREREQ(major, minor) 0
#endif
// This macro allows to test for the version of the GNU C++ compiler.
// Note that this also applies to compilers that masquerade as GCC,
// for example clang and the Intel C++ compiler for Linux.
// Use like:
// #if V8_GNUC_PREREQ(4, 3, 1)
// ...
// #endif
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#else
# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
#endif
// -----------------------------------------------------------------------------
// Operating system detection
//
// V8_OS_ANDROID - Android
// V8_OS_BSD - BSDish (Mac OS X, Net/Free/Open/DragonFlyBSD)
// V8_OS_CYGWIN - Cygwin
// V8_OS_DRAGONFLYBSD - DragonFlyBSD
// V8_OS_FREEBSD - FreeBSD
// V8_OS_LINUX - Linux
// V8_OS_MACOSX - Mac OS X
// V8_OS_NETBSD - NetBSD
// V8_OS_OPENBSD - OpenBSD
// V8_OS_POSIX - POSIX compatible (mostly everything except Windows)
// V8_OS_QNX - QNX Neutrino
// V8_OS_SOLARIS - Sun Solaris and OpenSolaris
// V8_OS_AIX - AIX
// V8_OS_WIN - Microsoft Windows
#if defined(__ANDROID__)
# define V8_OS_ANDROID 1
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__APPLE__)
# define V8_OS_BSD 1
# define V8_OS_MACOSX 1
# define V8_OS_POSIX 1
#elif defined(__CYGWIN__)
# define V8_OS_CYGWIN 1
# define V8_OS_POSIX 1
#elif defined(__linux__)
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__sun)
# define V8_OS_POSIX 1
# define V8_OS_SOLARIS 1
#elif defined(_AIX)
#define V8_OS_POSIX 1
#define V8_OS_AIX 1
#elif defined(__FreeBSD__)
# define V8_OS_BSD 1
# define V8_OS_FREEBSD 1
# define V8_OS_POSIX 1
#elif defined(__DragonFly__)
# define V8_OS_BSD 1
# define V8_OS_DRAGONFLYBSD 1
# define V8_OS_POSIX 1
#elif defined(__NetBSD__)
# define V8_OS_BSD 1
# define V8_OS_NETBSD 1
# define V8_OS_POSIX 1
#elif defined(__OpenBSD__)
# define V8_OS_BSD 1
# define V8_OS_OPENBSD 1
# define V8_OS_POSIX 1
#elif defined(__QNXNTO__)
# define V8_OS_POSIX 1
# define V8_OS_QNX 1
#elif defined(_WIN32)
# define V8_OS_WIN 1
#endif
// -----------------------------------------------------------------------------
// C library detection
//
// V8_LIBC_MSVCRT - MSVC libc
// V8_LIBC_BIONIC - Bionic libc
// V8_LIBC_BSD - BSD libc derivate
// V8_LIBC_GLIBC - GNU C library
// V8_LIBC_UCLIBC - uClibc
//
// Note that testing for libc must be done using #if not #ifdef. For example,
// to test for the GNU C library, use:
// #if V8_LIBC_GLIBC
// ...
// #endif
#if defined (_MSC_VER)
# define V8_LIBC_MSVCRT 1
#elif defined(__BIONIC__)
# define V8_LIBC_BIONIC 1
# define V8_LIBC_BSD 1
#elif defined(__UCLIBC__)
// Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC.
# define V8_LIBC_UCLIBC 1
#elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
# define V8_LIBC_GLIBC 1
#else
# define V8_LIBC_BSD V8_OS_BSD
#endif
// -----------------------------------------------------------------------------
// Compiler detection
//
// V8_CC_GNU - GCC, or clang in gcc mode
// V8_CC_INTEL - Intel C++
// V8_CC_MINGW - Minimalist GNU for Windows
// V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
// V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
// V8_CC_MSVC - Microsoft Visual C/C++, or clang in cl.exe mode
//
// C++11 feature detection
//
// V8_HAS_CXX11_ALIGNAS - alignas specifier supported
// V8_HAS_CXX11_ALIGNOF - alignof(type) operator supported
//
// 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))
// supported
// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) 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_VISIBILITY - __attribute__((visibility)) supported
// V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
// supported
// V8_HAS_BUILTIN_CLZ - __builtin_clz() supported
// V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported
// V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported
// V8_HAS_BUILTIN_FRAME_ADDRESS - __builtin_frame_address() supported
// V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported
// V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported
// V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_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_NOINLINE - __declspec(noinline) supported
// V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported
// V8_HAS_DECLSPEC_NORETURN - __declspec(noreturn) supported
// V8_HAS___FORCEINLINE - __forceinline supported
//
// Note that testing for compilers and/or features must be done using #if
// not #ifdef. For example, to test for Intel C++ Compiler, use:
// #if V8_CC_INTEL
// ...
// #endif
#if defined(__clang__)
#if defined(__GNUC__) // Clang in gcc mode.
# define V8_CC_GNU 1
#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_DEPRECATED (__has_attribute(deprecated))
# 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_VISIBILITY (__has_attribute(visibility))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(__has_attribute(warn_unused_result))
# define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
# define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
# define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address))
# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
# define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_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_CXX11_ALIGNAS (__has_feature(cxx_alignas))
#elif defined(__GNUC__)
# define V8_CC_GNU 1
# if defined(__INTEL_COMPILER) // Intel C++ also masquerades as GCC 3.2.0
# define V8_CC_INTEL 1
# endif
# if defined(__MINGW32__)
# define V8_CC_MINGW32 1
# endif
# if defined(__MINGW64__)
# define V8_CC_MINGW64 1
# endif
# 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.
// Works around "sorry, unimplemented: inlining failed" build errors with
// older compilers.
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 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_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_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
# define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_EXPECT (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))
# 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
#if defined(_MSC_VER)
# 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_NOINLINE 1
# define V8_HAS_DECLSPEC_SELECTANY 1
# define V8_HAS_DECLSPEC_NORETURN 1
# define V8_HAS___FORCEINLINE 1
#endif
// -----------------------------------------------------------------------------
// Helper macros
// A macro used to make better inlining. Don't bother for debug builds.
// Use like:
// V8_INLINE int GetZero() { return 0; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
# define V8_INLINE inline __attribute__((always_inline))
#elif !defined(DEBUG) && V8_HAS___FORCEINLINE
# define V8_INLINE __forceinline
#else
# define V8_INLINE inline
#endif
// A macro used to tell the compiler to never inline a particular function.
// Don't bother for debug builds.
// Use like:
// V8_NOINLINE int GetMinusOne() { return -1; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
# define V8_NOINLINE __attribute__((noinline))
#elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
# define V8_NOINLINE __declspec(noinline)
#else
# define V8_NOINLINE /* NOT SUPPORTED */
#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.
#if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATED(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATED(message, declarator) declarator
#endif
// A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated.
#if defined(V8_IMMINENT_DEPRECATION_WARNINGS) && \
V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATE_SOON(message, declarator) declarator
#endif
// A macro to provide the compiler with branch prediction information.
#if V8_HAS_BUILTIN_EXPECT
# define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
# define V8_LIKELY(condition) (__builtin_expect(!!(condition), 1))
#else
# define V8_UNLIKELY(condition) (condition)
# define V8_LIKELY(condition) (condition)
#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.
// Use like:
// int foo() WARN_UNUSED_RESULT;
#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
#endif
// clang-format on
#endif // V8CONFIG_H_

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,29 @@
// Copyright 2016 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_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#if defined(_WIN32)
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllexport)
#elif USING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllimport)
#else
#define V8_PLATFORM_EXPORT
#endif // BUILDING_V8_PLATFORM_SHARED
#else // defined(_WIN32)
// Setup for Linux shared library export.
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __attribute__((visibility("default")))
#else
#define V8_PLATFORM_EXPORT
#endif
#endif // defined(_WIN32)
#endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_

View File

@ -0,0 +1,78 @@
// Copyright 2014 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_LIBPLATFORM_LIBPLATFORM_H_
#define V8_LIBPLATFORM_LIBPLATFORM_H_
#include "libplatform/libplatform-export.h"
#include "libplatform/v8-tracing.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace platform {
enum class IdleTaskSupport { kDisabled, kEnabled };
enum class InProcessStackDumping { kDisabled, kEnabled };
enum class MessageLoopBehavior : bool {
kDoNotWait = false,
kWaitForWork = true
};
/**
* Returns a new instance of the default v8::Platform implementation.
*
* The caller will take ownership of the returned pointer. |thread_pool_size|
* is the number of worker threads to allocate for background jobs. If a value
* of zero is passed, a suitable default based on the current number of
* processors online will be chosen.
* If |idle_task_support| is enabled then the platform will accept idle
* tasks (IdleTasksEnabled will return true) and will rely on the embedder
* calling v8::platform::RunIdleTasks to process the idle tasks.
*/
V8_PLATFORM_EXPORT v8::Platform* CreateDefaultPlatform(
int thread_pool_size = 0,
IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
InProcessStackDumping in_process_stack_dumping =
InProcessStackDumping::kEnabled);
/**
* Pumps the message loop for the given isolate.
*
* 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
* through the |behavior| parameter, this call does not block if no task is
* pending. The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT bool PumpMessageLoop(
v8::Platform* platform, v8::Isolate* isolate,
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.
*
* 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
* created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
v8::Isolate* isolate,
double idle_time_in_seconds);
/**
* Attempts to set the tracing controller for the given platform.
*
* The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void SetTracingController(
v8::Platform* platform,
v8::platform::tracing::TracingController* tracing_controller);
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_LIBPLATFORM_H_

View File

@ -0,0 +1,270 @@
// Copyright 2016 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_LIBPLATFORM_V8_TRACING_H_
#define V8_LIBPLATFORM_V8_TRACING_H_
#include <fstream>
#include <memory>
#include <unordered_set>
#include <vector>
#include "libplatform/libplatform-export.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace base {
class Mutex;
} // namespace base
namespace platform {
namespace tracing {
const int kTraceMaxNumArgs = 2;
class V8_PLATFORM_EXPORT TraceObject {
public:
union ArgValue {
bool as_bool;
uint64_t as_uint;
int64_t as_int;
double as_double;
const void* as_pointer;
const char* as_string;
};
TraceObject() {}
~TraceObject();
void Initialize(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateDuration();
void InitializeForTesting(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
uint64_t duration, uint64_t cpu_duration);
int pid() const { return pid_; }
int tid() const { return tid_; }
char phase() const { return phase_; }
const uint8_t* category_enabled_flag() const {
return category_enabled_flag_;
}
const char* name() const { return name_; }
const char* scope() const { return scope_; }
uint64_t id() const { return id_; }
uint64_t bind_id() const { return bind_id_; }
int num_args() const { return num_args_; }
const char** arg_names() { return arg_names_; }
uint8_t* arg_types() { return arg_types_; }
ArgValue* arg_values() { return arg_values_; }
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables() {
return arg_convertables_;
}
unsigned int flags() const { return flags_; }
int64_t ts() { return ts_; }
int64_t tts() { return tts_; }
uint64_t duration() { return duration_; }
uint64_t cpu_duration() { return cpu_duration_; }
private:
int pid_;
int tid_;
char phase_;
const char* name_;
const char* scope_;
const uint8_t* category_enabled_flag_;
uint64_t id_;
uint64_t bind_id_;
int num_args_ = 0;
const char* arg_names_[kTraceMaxNumArgs];
uint8_t arg_types_[kTraceMaxNumArgs];
ArgValue arg_values_[kTraceMaxNumArgs];
std::unique_ptr<v8::ConvertableToTraceFormat>
arg_convertables_[kTraceMaxNumArgs];
char* parameter_copy_storage_ = nullptr;
unsigned int flags_;
int64_t ts_;
int64_t tts_;
uint64_t duration_;
uint64_t cpu_duration_;
// Disallow copy and assign
TraceObject(const TraceObject&) = delete;
void operator=(const TraceObject&) = delete;
};
class V8_PLATFORM_EXPORT TraceWriter {
public:
TraceWriter() {}
virtual ~TraceWriter() {}
virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
virtual void Flush() = 0;
static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
private:
// Disallow copy and assign
TraceWriter(const TraceWriter&) = delete;
void operator=(const TraceWriter&) = delete;
};
class V8_PLATFORM_EXPORT TraceBufferChunk {
public:
explicit TraceBufferChunk(uint32_t seq);
void Reset(uint32_t new_seq);
bool IsFull() const { return next_free_ == kChunkSize; }
TraceObject* AddTraceEvent(size_t* event_index);
TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
uint32_t seq() const { return seq_; }
size_t size() const { return next_free_; }
static const size_t kChunkSize = 64;
private:
size_t next_free_ = 0;
TraceObject chunk_[kChunkSize];
uint32_t seq_;
// Disallow copy and assign
TraceBufferChunk(const TraceBufferChunk&) = delete;
void operator=(const TraceBufferChunk&) = delete;
};
class V8_PLATFORM_EXPORT TraceBuffer {
public:
TraceBuffer() {}
virtual ~TraceBuffer() {}
virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
virtual bool Flush() = 0;
static const size_t kRingBufferChunks = 1024;
static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
TraceWriter* trace_writer);
private:
// Disallow copy and assign
TraceBuffer(const TraceBuffer&) = delete;
void operator=(const TraceBuffer&) = delete;
};
// Options determines how the trace buffer stores data.
enum TraceRecordMode {
// Record until the trace buffer is full.
RECORD_UNTIL_FULL,
// Record until the user ends the trace. The trace buffer is a fixed size
// and we use it as a ring buffer during recording.
RECORD_CONTINUOUSLY,
// Record until the trace buffer is full, but with a huge buffer size.
RECORD_AS_MUCH_AS_POSSIBLE,
// Echo to console. Events are discarded.
ECHO_TO_CONSOLE,
};
class V8_PLATFORM_EXPORT TraceConfig {
public:
typedef std::vector<std::string> StringList;
static TraceConfig* CreateDefaultTraceConfig();
TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
bool IsSystraceEnabled() const { return enable_systrace_; }
bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
void EnableSystrace() { enable_systrace_ = true; }
void EnableArgumentFilter() { enable_argument_filter_ = true; }
void AddIncludedCategory(const char* included_category);
bool IsCategoryGroupEnabled(const char* category_group) const;
private:
TraceRecordMode record_mode_;
bool enable_systrace_ : 1;
bool enable_argument_filter_ : 1;
StringList included_categories_;
// Disallow copy and assign
TraceConfig(const TraceConfig&) = delete;
void operator=(const TraceConfig&) = delete;
};
class V8_PLATFORM_EXPORT TracingController {
public:
enum Mode { DISABLED = 0, RECORDING_MODE };
// The pointer returned from GetCategoryGroupEnabledInternal() 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 {
// Category group enabled for the recording mode.
ENABLED_FOR_RECORDING = 1 << 0,
// Category group enabled by SetEventCallbackEnabled().
ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
// Category group enabled to export events to ETW.
ENABLED_FOR_ETW_EXPORT = 1 << 3
};
TracingController();
~TracingController();
void Initialize(TraceBuffer* trace_buffer);
const uint8_t* GetCategoryGroupEnabled(const char* category_group);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle);
void StartTracing(TraceConfig* trace_config);
void StopTracing();
void AddTraceStateObserver(Platform::TraceStateObserver* observer);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
void UpdateCategoryGroupEnabledFlag(size_t category_index);
void UpdateCategoryGroupEnabledFlags();
std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_;
Mode mode_ = DISABLED;
// Disallow copy and assign
TracingController(const TracingController&) = delete;
void operator=(const TracingController&) = delete;
};
} // namespace tracing
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_V8_TRACING_H_

View File

@ -0,0 +1,255 @@
// 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

@ -0,0 +1,13 @@
// Copyright 2016 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_INSPECTOR_PROTOCOL_H_
#define V8_V8_INSPECTOR_PROTOCOL_H_
#include "inspector/Debugger.h" // NOLINT(build/include)
#include "inspector/Runtime.h" // NOLINT(build/include)
#include "inspector/Schema.h" // NOLINT(build/include)
#include "v8-inspector.h" // NOLINT(build/include)
#endif // V8_V8_INSPECTOR_PROTOCOL_H_

View File

@ -0,0 +1,267 @@
// Copyright 2016 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_INSPECTOR_H_
#define V8_V8_INSPECTOR_H_
#include <stdint.h>
#include <cctype>
#include <memory>
#include "v8.h" // NOLINT(build/include)
namespace v8_inspector {
namespace protocol {
namespace Debugger {
namespace API {
class SearchMatch;
}
}
namespace Runtime {
namespace API {
class RemoteObject;
class StackTrace;
}
}
namespace Schema {
namespace API {
class Domain;
}
}
} // namespace protocol
class V8_EXPORT StringView {
public:
StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {}
StringView(const uint8_t* characters, size_t length)
: m_is8Bit(true), m_length(length), m_characters8(characters) {}
StringView(const uint16_t* characters, size_t length)
: m_is8Bit(false), m_length(length), m_characters16(characters) {}
bool is8Bit() const { return m_is8Bit; }
size_t length() const { return m_length; }
// TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used
// here.
const uint8_t* characters8() const { return m_characters8; }
const uint16_t* characters16() const { return m_characters16; }
private:
bool m_is8Bit;
size_t m_length;
union {
const uint8_t* m_characters8;
const uint16_t* m_characters16;
};
};
class V8_EXPORT StringBuffer {
public:
virtual ~StringBuffer() {}
virtual const StringView& string() = 0;
// This method copies contents.
static std::unique_ptr<StringBuffer> create(const StringView&);
};
class V8_EXPORT V8ContextInfo {
public:
V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId,
const StringView& humanReadableName)
: context(context),
contextGroupId(contextGroupId),
humanReadableName(humanReadableName),
hasMemoryOnConsole(false) {}
v8::Local<v8::Context> context;
// Each v8::Context is a part of a group. The group id must be non-zero.
int contextGroupId;
StringView humanReadableName;
StringView origin;
StringView auxData;
bool hasMemoryOnConsole;
static int executionContextId(v8::Local<v8::Context> context);
private:
// Disallow copying and allocating this one.
enum NotNullTagEnum { NotNullLiteral };
void* operator new(size_t) = delete;
void* operator new(size_t, NotNullTagEnum, void*) = delete;
void* operator new(size_t, void*) = delete;
V8ContextInfo(const V8ContextInfo&) = delete;
V8ContextInfo& operator=(const V8ContextInfo&) = delete;
};
class V8_EXPORT V8StackTrace {
public:
virtual bool isEmpty() const = 0;
virtual StringView topSourceURL() const = 0;
virtual int topLineNumber() const = 0;
virtual int topColumnNumber() const = 0;
virtual StringView topScriptId() const = 0;
virtual StringView topFunctionName() const = 0;
virtual ~V8StackTrace() {}
virtual std::unique_ptr<protocol::Runtime::API::StackTrace>
buildInspectorObject() const = 0;
virtual std::unique_ptr<StringBuffer> toString() const = 0;
// Safe to pass between threads, drops async chain.
virtual std::unique_ptr<V8StackTrace> clone() = 0;
};
class V8_EXPORT V8InspectorSession {
public:
virtual ~V8InspectorSession() {}
// Cross-context inspectable values (DOM nodes in different worlds, etc.).
class V8_EXPORT Inspectable {
public:
virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0;
virtual ~Inspectable() {}
};
virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0;
// Dispatching protocol messages.
static bool canDispatchMethod(const StringView& method);
virtual void dispatchProtocolMessage(const StringView& message) = 0;
virtual std::unique_ptr<StringBuffer> stateJSON() = 0;
virtual std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
supportedDomains() = 0;
// Debugger actions.
virtual void schedulePauseOnNextStatement(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void cancelPauseOnNextStatement() = 0;
virtual void breakProgram(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void setSkipAllPauses(bool) = 0;
virtual void resume() = 0;
virtual void stepOver() = 0;
virtual std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
searchInTextByLines(const StringView& text, const StringView& query,
bool caseSensitive, bool isRegex) = 0;
// Remote objects.
virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject(
v8::Local<v8::Context>, v8::Local<v8::Value>,
const StringView& groupName) = 0;
virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error,
const StringView& objectId, v8::Local<v8::Value>*,
v8::Local<v8::Context>*,
std::unique_ptr<StringBuffer>* objectGroup) = 0;
virtual void releaseObjectGroup(const StringView&) = 0;
};
class V8_EXPORT V8InspectorClient {
public:
virtual ~V8InspectorClient() {}
virtual void runMessageLoopOnPause(int contextGroupId) {}
virtual void quitMessageLoopOnPause() {}
virtual void runIfWaitingForDebugger(int contextGroupId) {}
virtual void muteMetrics(int contextGroupId) {}
virtual void unmuteMetrics(int contextGroupId) {}
virtual void beginUserGesture() {}
virtual void endUserGesture() {}
virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) {
return nullptr;
}
virtual bool formatAccessorsAsProperties(v8::Local<v8::Value>) {
return false;
}
virtual bool isInspectableHeapObject(v8::Local<v8::Object>) { return true; }
virtual v8::Local<v8::Context> ensureDefaultContextInGroup(
int contextGroupId) {
return v8::Local<v8::Context>();
}
virtual void beginEnsureAllContextsInGroup(int contextGroupId) {}
virtual void endEnsureAllContextsInGroup(int contextGroupId) {}
virtual void installAdditionalCommandLineAPI(v8::Local<v8::Context>,
v8::Local<v8::Object>) {}
virtual void consoleAPIMessage(int contextGroupId,
v8::Isolate::MessageErrorLevel level,
const StringView& message,
const StringView& url, unsigned lineNumber,
unsigned columnNumber, V8StackTrace*) {}
virtual v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*,
v8::Local<v8::Context>) {
return v8::MaybeLocal<v8::Value>();
}
virtual void consoleTime(const StringView& title) {}
virtual void consoleTimeEnd(const StringView& title) {}
virtual void consoleTimeStamp(const StringView& title) {}
virtual void consoleClear(int contextGroupId) {}
virtual double currentTimeMS() { return 0; }
typedef void (*TimerCallback)(void*);
virtual void startRepeatingTimer(double, TimerCallback, void* data) {}
virtual void cancelTimer(void* data) {}
// TODO(dgozman): this was added to support service worker shadow page. We
// should not connect at all.
virtual bool canExecuteScripts(int contextGroupId) { return true; }
};
class V8_EXPORT V8Inspector {
public:
static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*);
virtual ~V8Inspector() {}
// Contexts instrumentation.
virtual void contextCreated(const V8ContextInfo&) = 0;
virtual void contextDestroyed(v8::Local<v8::Context>) = 0;
virtual void resetContextGroup(int contextGroupId) = 0;
// Various instrumentation.
virtual void idleStarted() = 0;
virtual void idleFinished() = 0;
// Async stack traces instrumentation.
virtual void asyncTaskScheduled(const StringView& taskName, void* task,
bool recurring) = 0;
virtual void asyncTaskCanceled(void* task) = 0;
virtual void asyncTaskStarted(void* task) = 0;
virtual void asyncTaskFinished(void* task) = 0;
virtual void allAsyncTasksCanceled() = 0;
// Exceptions instrumentation.
virtual unsigned exceptionThrown(
v8::Local<v8::Context>, const StringView& message,
v8::Local<v8::Value> exception, const StringView& detailedMessage,
const StringView& url, unsigned lineNumber, unsigned columnNumber,
std::unique_ptr<V8StackTrace>, int scriptId) = 0;
virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId,
const StringView& message) = 0;
// Connection.
class V8_EXPORT Channel {
public:
virtual ~Channel() {}
virtual void sendResponse(int callId,
std::unique_ptr<StringBuffer> message) = 0;
virtual void sendNotification(std::unique_ptr<StringBuffer> message) = 0;
virtual void flushProtocolNotifications() = 0;
};
virtual std::unique_ptr<V8InspectorSession> connect(
int contextGroupId, Channel*, const StringView& state) = 0;
// API methods.
virtual std::unique_ptr<V8StackTrace> createStackTrace(
v8::Local<v8::StackTrace>) = 0;
virtual std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) = 0;
};
} // namespace v8_inspector
#endif // V8_V8_INSPECTOR_H_

View File

@ -0,0 +1,227 @@
// Copyright 2013 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_PLATFORM_H_
#define V8_V8_PLATFORM_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
namespace v8 {
class Isolate;
/**
* A Task represents a unit of work.
*/
class Task {
public:
virtual ~Task() = default;
virtual void Run() = 0;
};
/**
* An IdleTask represents a unit of work to be performed in idle time.
* The Run method is invoked with an argument that specifies the deadline in
* seconds returned by MonotonicallyIncreasingTime().
* The idle task is expected to complete by this deadline.
*/
class IdleTask {
public:
virtual ~IdleTask() = default;
virtual void Run(double deadline_in_seconds) = 0;
};
/**
* The interface represents complex arguments to trace events.
*/
class ConvertableToTraceFormat {
public:
virtual ~ConvertableToTraceFormat() = default;
/**
* Append the class info to the provided |out| string. The appended
* data must be a valid JSON object. Strings must be properly quoted, and
* escaped. There is no processing applied to the content after it is
* appended.
*/
virtual void AppendAsTraceFormat(std::string* out) const = 0;
};
/**
* V8 Platform abstraction layer.
*
* The embedder has to provide an implementation of this interface before
* initializing the rest of V8.
*/
class Platform {
public:
/**
* 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.
* The name parameter is a category group for example:
* TRACE_EVENT0("v8,parse", "V8.Parse")
* The pointer returned points to a value with zero or more of the bits
* defined in CategoryGroupEnabledFlags.
**/
virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
static uint8_t no = 0;
return &no;
}
/**
* Gets the category group name of the given category_enabled_flag pointer.
* 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
* tracing and the category of the particular trace are enabled. It is not
* advisable to call this function on its own; it is really only meant to be
* used by the trace macros. The returned handle can be used by
* UpdateTraceEventDuration to update the duration of COMPLETE events.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values, 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.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) {
return AddTraceEvent(phase, category_enabled_flag, name, scope, id, bind_id,
num_args, arg_names, arg_types, arg_values, flags);
}
/**
* Sets the duration field of a COMPLETE trace event. It must be called with
* the handle returned from AddTraceEvent().
**/
virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {}
class TraceStateObserver {
public:
virtual ~TraceStateObserver() = default;
virtual void OnTraceEnabled() = 0;
virtual void OnTraceDisabled() = 0;
};
/** Adds tracing state change observer. */
virtual void AddTraceStateObserver(TraceStateObserver*) {}
/** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
typedef void (*StackTracePrinter)();
/**
* Returns a function pointer that print a stack trace of the current stack
* on invocation. Disables printing of the stack trace if nullptr.
*/
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
};
} // namespace v8
#endif // V8_V8_PLATFORM_H_

View File

@ -0,0 +1,912 @@
// Copyright 2010 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_PROFILER_H_
#define V8_V8_PROFILER_H_
#include <unordered_set>
#include <vector>
#include "v8.h" // NOLINT(build/include)
/**
* Profiler support for the V8 JavaScript engine.
*/
namespace v8 {
class HeapGraphNode;
struct HeapStatsUpdate;
typedef uint32_t SnapshotObjectId;
struct CpuProfileDeoptFrame {
int script_id;
size_t position;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
#endif
namespace v8 {
struct V8_EXPORT CpuProfileDeoptInfo {
/** A pointer to a static string owned by v8. */
const char* deopt_reason;
std::vector<CpuProfileDeoptFrame> stack;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
#endif
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.
struct TickSample {
// Internal profiling (with --prof + tools/$OS-tick-processor) wants to
// include the runtime function we're calling. Externally exposed tick
// samples don't care.
enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
TickSample()
: state(OTHER),
pc(nullptr),
external_callback_entry(nullptr),
frames_count(0),
has_external_callback(false),
update_stats(true) {}
/**
* Initialize a tick sample from the isolate.
* \param isolate The isolate.
* \param state Execution state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param update_stats Whether update the sample to the aggregated stats.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
*/
void Init(Isolate* isolate, const v8::RegisterState& state,
RecordCEntryFrame record_c_entry_frame, bool update_stats,
bool use_simulator_reg_state = true);
/**
* Get a call stack sample from the isolate.
* \param isolate The isolate.
* \param state Register state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param frames Caller allocated buffer to store stack frames.
* \param frames_limit Maximum number of frames to capture. The buffer must
* be large enough to hold the number of frames.
* \param sample_info The sample info is filled up by the function
* provides number of actual captured stack frames and
* the current VM state.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
* \note GetStackSample is thread and signal safe and should only be called
* when the JS thread is paused or interrupted.
* Otherwise the behavior is undefined.
*/
static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
RecordCEntryFrame record_c_entry_frame,
void** frames, size_t frames_limit,
v8::SampleInfo* sample_info,
bool use_simulator_reg_state = true);
StateTag state; // The state of the VM.
void* pc; // Instruction pointer.
union {
void* tos; // Top stack value (*sp).
void* external_callback_entry;
};
static const unsigned kMaxFramesCountLog2 = 8;
static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
void* stack[kMaxFramesCount]; // Call stack.
unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
bool has_external_callback : 1;
bool update_stats : 1; // Whether the sample should update aggregated stats.
};
/**
* CpuProfileNode represents a node in a call graph.
*/
class V8_EXPORT CpuProfileNode {
public:
struct LineTick {
/** The 1-based number of the source line where the function originates. */
int line;
/** The count of samples associated with the source line. */
unsigned int hit_count;
};
/** Returns function name (empty string for anonymous functions.) */
Local<String> GetFunctionName() const;
/**
* Returns function name (empty string for anonymous functions.)
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetFunctionNameStr() const;
/** Returns id of the script where function is located. */
int GetScriptId() const;
/** Returns resource name for script from where the function originates. */
Local<String> GetScriptResourceName() const;
/**
* Returns resource name for script from where the function originates.
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetScriptResourceNameStr() const;
/**
* Returns the number, 1-based, of the line where the function originates.
* kNoLineNumberInfo if no line number information is available.
*/
int GetLineNumber() const;
/**
* Returns 1-based number of the column where the function originates.
* kNoColumnNumberInfo if no column number information is available.
*/
int GetColumnNumber() const;
/**
* Returns the number of the function's source lines that collect the samples.
*/
unsigned int GetHitLineCount() const;
/** Returns the set of source lines that collect the samples.
* The caller allocates buffer and responsible for releasing it.
* True if all available entries are copied, otherwise false.
* The function copies nothing if buffer is not large enough.
*/
bool GetLineTicks(LineTick* entries, unsigned int length) const;
/** Returns bailout reason for the function
* if the optimization was disabled for it.
*/
const char* GetBailoutReason() const;
/**
* Returns the count of samples where the function was currently executing.
*/
unsigned GetHitCount() const;
/** Returns function entry UID. */
V8_DEPRECATE_SOON(
"Use GetScriptId, GetLineNumber, and GetColumnNumber instead.",
unsigned GetCallUid() const);
/** Returns id of the node. The id is unique within the tree */
unsigned GetNodeId() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child node by index. */
const CpuProfileNode* GetChild(int index) const;
/** Retrieves deopt infos for the node. */
const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* CpuProfile contains a CPU profile in a form of top-down call tree
* (from main() down to functions that do all the work).
*/
class V8_EXPORT CpuProfile {
public:
/** Returns CPU profile title. */
Local<String> GetTitle() const;
/** Returns the root node of the top down call tree. */
const CpuProfileNode* GetTopDownRoot() const;
/**
* Returns number of samples recorded. The samples are not recorded unless
* |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
*/
int GetSamplesCount() const;
/**
* Returns profile node corresponding to the top frame the sample at
* the given index.
*/
const CpuProfileNode* GetSample(int index) const;
/**
* Returns the timestamp of the sample. The timestamp is the number of
* microseconds since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetSampleTimestamp(int index) const;
/**
* Returns time when the profile recording was started (in microseconds)
* since some unspecified starting point.
*/
int64_t GetStartTime() const;
/**
* Returns time when the profile recording was stopped (in microseconds)
* since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetEndTime() const;
/**
* Deletes the profile and removes it from CpuProfiler's list.
* All pointers to nodes previously returned become invalid.
*/
void Delete();
};
/**
* Interface for controlling CPU profiling. Instance of the
* profiler can be created using v8::CpuProfiler::New method.
*/
class V8_EXPORT CpuProfiler {
public:
/**
* Creates a new CPU profiler for the |isolate|. The isolate must be
* initialized. The profiler object must be disposed after use by calling
* |Dispose| method.
*/
static CpuProfiler* New(Isolate* isolate);
/**
* Disposes the CPU profiler object.
*/
void Dispose();
/**
* Changes default CPU profiler sampling interval to the specified number
* of microseconds. Default interval is 1000us. This method must be called
* when there are no profiles being recorded.
*/
void SetSamplingInterval(int us);
/**
* Starts collecting CPU profile. Title may be an empty string. It
* is allowed to have several profiles being collected at
* once. Attempts to start collecting several profiles with the same
* title are silently ignored. While collecting a profile, functions
* from all security contexts are included in it. The token-based
* filtering is only performed when querying for a profile.
*
* |record_samples| parameter controls whether individual samples should
* be recorded in addition to the aggregated tree.
*/
void StartProfiling(Local<String> title, bool record_samples = false);
/**
* Stops collecting CPU profile with a given title and returns it.
* If the title given is empty, finishes the last profile started.
*/
CpuProfile* StopProfiling(Local<String> title);
/**
* Force collection of a sample. Must be called on the VM thread.
* Recording the forced sample does not contribute to the aggregated
* profile statistics.
*/
void CollectSample();
/**
* Tells the profiler whether the embedder is idle.
*/
void SetIdle(bool is_idle);
private:
CpuProfiler();
~CpuProfiler();
CpuProfiler(const CpuProfiler&);
CpuProfiler& operator=(const CpuProfiler&);
};
/**
* HeapSnapshotEdge represents a directed connection between heap
* graph nodes: from retainers to retained nodes.
*/
class V8_EXPORT HeapGraphEdge {
public:
enum Type {
kContextVariable = 0, // A variable from a function context.
kElement = 1, // An element of an array.
kProperty = 2, // A named object property.
kInternal = 3, // A link that can't be accessed from JS,
// thus, its name isn't a real property name
// (e.g. parts of a ConsString).
kHidden = 4, // A link that is needed for proper sizes
// calculation, but may be hidden from user.
kShortcut = 5, // A link that must not be followed during
// sizes calculation.
kWeak = 6 // A weak reference (ignored by the GC).
};
/** Returns edge type (see HeapGraphEdge::Type). */
Type GetType() const;
/**
* Returns edge name. This can be a variable name, an element index, or
* a property name.
*/
Local<Value> GetName() const;
/** Returns origin node. */
const HeapGraphNode* GetFromNode() const;
/** Returns destination node. */
const HeapGraphNode* GetToNode() const;
};
/**
* HeapGraphNode represents a node in a heap graph.
*/
class V8_EXPORT HeapGraphNode {
public:
enum Type {
kHidden = 0, // Hidden node, may be filtered when shown to user.
kArray = 1, // An array of elements.
kString = 2, // A string.
kObject = 3, // A JS object (except for arrays and strings).
kCode = 4, // Compiled code.
kClosure = 5, // Function closure.
kRegExp = 6, // RegExp.
kHeapNumber = 7, // Number stored in the heap.
kNative = 8, // Native object (not from V8 heap).
kSynthetic = 9, // Synthetic object, usualy used for grouping
// snapshot items together.
kConsString = 10, // Concatenated string. A pair of pointers to strings.
kSlicedString = 11, // Sliced string. A fragment of another string.
kSymbol = 12 // A Symbol (ES6).
};
/** Returns node type (see HeapGraphNode::Type). */
Type GetType() const;
/**
* Returns node name. Depending on node's type this can be the name
* of the constructor (for objects), the name of the function (for
* closures), string value, or an empty string (for compiled code).
*/
Local<String> GetName() const;
/**
* Returns node id. For the same heap object, the id remains the same
* across all snapshots.
*/
SnapshotObjectId GetId() const;
/** Returns node's own size, in bytes. */
size_t GetShallowSize() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child by index. */
const HeapGraphEdge* GetChild(int index) const;
};
/**
* An interface for exporting data from V8, using "push" model.
*/
class V8_EXPORT OutputStream { // NOLINT
public:
enum WriteResult {
kContinue = 0,
kAbort = 1
};
virtual ~OutputStream() {}
/** Notify about the end of stream. */
virtual void EndOfStream() = 0;
/** Get preferred output chunk size. Called only once. */
virtual int GetChunkSize() { return 1024; }
/**
* Writes the next chunk of snapshot data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
/**
* Writes the next chunk of heap stats data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
return kAbort;
}
};
/**
* HeapSnapshots record the state of the JS heap at some moment.
*/
class V8_EXPORT HeapSnapshot {
public:
enum SerializationFormat {
kJSON = 0 // See format description near 'Serialize' method.
};
/** Returns the root node of the heap graph. */
const HeapGraphNode* GetRoot() const;
/** Returns a node by its id. */
const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
/** Returns total nodes count in the snapshot. */
int GetNodesCount() const;
/** Returns a node by index. */
const HeapGraphNode* GetNode(int index) const;
/** Returns a max seen JS object Id. */
SnapshotObjectId GetMaxSnapshotJSObjectId() const;
/**
* Deletes the snapshot and removes it from HeapProfiler's list.
* All pointers to nodes, edges and paths previously returned become
* invalid.
*/
void Delete();
/**
* Prepare a serialized representation of the snapshot. The result
* is written into the stream provided in chunks of specified size.
* The total length of the serialized snapshot is unknown in
* advance, it can be roughly equal to JS heap size (that means,
* it can be really big - tens of megabytes).
*
* For the JSON format, heap contents are represented as an object
* with the following structure:
*
* {
* snapshot: {
* title: "...",
* uid: nnn,
* meta: { meta-info },
* node_count: nnn,
* edge_count: nnn
* },
* nodes: [nodes array],
* edges: [edges array],
* strings: [strings array]
* }
*
* Nodes reference strings, other nodes, and edges by their indexes
* in corresponding arrays.
*/
void Serialize(OutputStream* stream,
SerializationFormat format = kJSON) const;
};
/**
* An interface for reporting progress and controlling long-running
* activities.
*/
class V8_EXPORT ActivityControl { // NOLINT
public:
enum ControlOption {
kContinue = 0,
kAbort = 1
};
virtual ~ActivityControl() {}
/**
* Notify about current progress. The activity can be stopped by
* returning kAbort as the callback result.
*/
virtual ControlOption ReportProgressValue(int done, int total) = 0;
};
/**
* AllocationProfile is a sampled profile of allocations done by the program.
* This is structured as a call-graph.
*/
class V8_EXPORT AllocationProfile {
public:
struct Allocation {
/**
* Size of the sampled allocation object.
*/
size_t size;
/**
* The number of objects of such size that were sampled.
*/
unsigned int count;
};
/**
* Represents a node in the call-graph.
*/
struct Node {
/**
* Name of the function. May be empty for anonymous functions or if the
* script corresponding to this function has been unloaded.
*/
Local<String> name;
/**
* Name of the script containing the function. May be empty if the script
* name is not available, or if the script has been unloaded.
*/
Local<String> script_name;
/**
* id of the script where the function is located. May be equal to
* v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.
*/
int script_id;
/**
* Start position of the function in the script.
*/
int start_position;
/**
* 1-indexed line number where the function starts. May be
* kNoLineNumberInfo if no line number information is available.
*/
int line_number;
/**
* 1-indexed column number where the function starts. May be
* kNoColumnNumberInfo if no line number information is available.
*/
int column_number;
/**
* List of callees called from this node for which we have sampled
* allocations. The lifetime of the children is scoped to the containing
* AllocationProfile.
*/
std::vector<Node*> children;
/**
* List of self allocations done by this node in the call-graph.
*/
std::vector<Allocation> allocations;
};
/**
* 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
* containing AllocationProfile.
*/
virtual Node* GetRootNode() = 0;
virtual ~AllocationProfile() {}
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* Interface for controlling heap profiling. Instance of the
* profiler can be retrieved using v8::Isolate::GetHeapProfiler.
*/
class V8_EXPORT HeapProfiler {
public:
enum SamplingFlags {
kSamplingNoFlags = 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.
*/
typedef RetainerInfos (*GetRetainerInfosCallback)(v8::Isolate* isolate);
/**
* 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. */
int GetSnapshotCount();
/** Returns a snapshot by index. */
const HeapSnapshot* GetHeapSnapshot(int index);
/**
* Returns SnapshotObjectId for a heap object referenced by |value| if
* it has been seen by the heap profiler, kUnknownObjectId otherwise.
*/
SnapshotObjectId GetObjectId(Local<Value> value);
/**
* Returns heap object with given SnapshotObjectId if the object is alive,
* otherwise empty handle is returned.
*/
Local<Value> FindObjectById(SnapshotObjectId id);
/**
* Clears internal map from SnapshotObjectId to heap object. The new objects
* will not be added into it unless a heap snapshot is taken or heap object
* tracking is kicked off.
*/
void ClearObjectIds();
/**
* A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
* it in case heap profiler cannot find id for the object passed as
* parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
*/
static const SnapshotObjectId kUnknownObjectId = 0;
/**
* Callback interface for retrieving user friendly names of global objects.
*/
class ObjectNameResolver {
public:
/**
* Returns name to be used in the heap snapshot for given node. Returned
* string must stay alive until snapshot collection is completed.
*/
virtual const char* GetName(Local<Object> object) = 0;
protected:
virtual ~ObjectNameResolver() {}
};
/**
* Takes a heap snapshot and returns it.
*/
const HeapSnapshot* TakeHeapSnapshot(
ActivityControl* control = NULL,
ObjectNameResolver* global_object_name_resolver = NULL);
/**
* Starts tracking of heap objects population statistics. After calling
* this method, all heap objects relocations done by the garbage collector
* are being registered.
*
* |track_allocations| parameter controls whether stack trace of each
* allocation in the heap will be recorded and reported as part of
* HeapSnapshot.
*/
void StartTrackingHeapObjects(bool track_allocations = false);
/**
* Adds a new time interval entry to the aggregated statistics array. The
* time interval entry contains information on the current heap objects
* population size. The method also updates aggregated statistics and
* reports updates for all previous time intervals via the OutputStream
* object. Updates on each time interval are provided as a stream of the
* HeapStatsUpdate structure instances.
* If |timestamp_us| is supplied, timestamp of the new entry will be written
* into it. The return value of the function is the last seen heap object Id.
*
* StartTrackingHeapObjects must be called before the first call to this
* method.
*/
SnapshotObjectId GetHeapStats(OutputStream* stream,
int64_t* timestamp_us = NULL);
/**
* Stops tracking of heap objects population statistics, cleans up all
* collected data. StartHeapObjectsTracking must be called again prior to
* calling GetHeapStats next time.
*/
void StopTrackingHeapObjects();
/**
* Starts gathering a sampling heap profile. A sampling heap profile is
* similar to tcmalloc's heap profiler and Go's mprof. It samples object
* allocations and builds an online 'sampling' heap profile. At any point in
* time, this profile is expected to be a representative sample of objects
* currently live in the system. Each sampled allocation includes the stack
* trace at the time of allocation, which makes this really useful for memory
* leak detection.
*
* This mechanism is intended to be cheap enough that it can be used in
* production with minimal performance overhead.
*
* Allocations are sampled using a randomized Poisson process. On average, one
* allocation will be sampled every |sample_interval| bytes allocated. The
* |stack_depth| parameter controls the maximum number of stack frames to be
* captured on each allocation.
*
* NOTE: This is a proof-of-concept at this point. Right now we only sample
* newspace allocations. Support for paged space allocation (e.g. pre-tenured
* objects, large objects, code objects, etc.) and native allocations
* doesn't exist yet, but is anticipated in the future.
*
* Objects allocated before the sampling is started will not be included in
* the profile.
*
* Returns false if a sampling heap profiler is already running.
*/
bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
int stack_depth = 16,
SamplingFlags flags = kSamplingNoFlags);
/**
* Stops the sampling heap profile and discards the current profile.
*/
void StopSamplingHeapProfiler();
/**
* Returns the sampled profile of allocations allocated (and still live) since
* StartSamplingHeapProfiler was called. The ownership of the pointer is
* transfered to the caller. Returns nullptr if sampling heap profiler is not
* active.
*/
AllocationProfile* GetAllocationProfile();
/**
* Deletes all snapshots taken. All previously returned pointers to
* snapshots and their contents become invalid after this call.
*/
void DeleteAllHeapSnapshots();
/** Binds a callback to embedder's class ID. */
void SetWrapperClassInfoProvider(
uint16_t class_id,
WrapperInfoCallback callback);
void SetGetRetainerInfosCallback(GetRetainerInfosCallback callback);
/**
* Default value of persistent handle class ID. Must not be used to
* define a class. Can be used to reset a class of a persistent
* handle.
*/
static const uint16_t kPersistentHandleNoClassId = 0;
/** Returns memory used for profiler internal data and snapshots. */
size_t GetProfilerMemorySize();
private:
HeapProfiler();
~HeapProfiler();
HeapProfiler(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.
* See HeapProfiler::GetHeapStats.
*/
struct HeapStatsUpdate {
HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
: index(index), count(count), size(size) { }
uint32_t index; // Index of the time interval that was changed.
uint32_t count; // New value of count field for the interval with this index.
uint32_t size; // New value of size field for the interval with this index.
};
} // namespace v8
#endif // V8_V8_PROFILER_H_

View File

@ -0,0 +1,48 @@
// Copyright 2010 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_TEST_H_
#define V8_V8_TEST_H_
#include "v8.h" // NOLINT(build/include)
/**
* Testing support for the V8 JavaScript engine.
*/
namespace v8 {
class V8_EXPORT Testing {
public:
enum StressType {
kStressTypeOpt,
kStressTypeDeopt
};
/**
* Set the type of stressing to do. The default if not set is kStressTypeOpt.
*/
static void SetStressRunType(StressType type);
/**
* Get the number of runs of a given test that is required to get the full
* stress coverage.
*/
static int GetStressRuns();
/**
* Indicate the number of the run which is about to start. The value of run
* should be between 0 and one less than the result from GetStressRuns()
*/
static void PrepareStressRun(int run);
/**
* Force deoptimization of all functions.
*/
static void DeoptimizeAll(Isolate* isolate);
};
} // namespace v8
#endif // V8_V8_TEST_H_

View File

@ -0,0 +1,655 @@
// Copyright 2014 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_UTIL_H_
#define V8_UTIL_H_
#include "v8.h" // NOLINT(build/include)
#include <assert.h>
#include <map>
#include <vector>
/**
* Support for Persistent containers.
*
* C++11 embedders can use STL containers with Global values,
* but pre-C++11 does not support the required move semantic and hence
* may want these container classes.
*/
namespace v8 {
typedef uintptr_t PersistentContainerValue;
static const uintptr_t kPersistentContainerNotFound = 0;
enum PersistentContainerCallbackType {
kNotWeak,
// These correspond to v8::WeakCallbackType
kWeakWithParameter,
kWeakWithInternalFields,
kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
};
/**
* A default trait implemenation for PersistentValueMap which uses std::map
* as a backing map.
*
* Users will have to implement their own weak callbacks & dispose traits.
*/
template<typename K, typename V>
class StdMapTraits {
public:
// STL map & related:
typedef std::map<K, PersistentContainerValue> Impl;
typedef typename Impl::iterator Iterator;
static bool Empty(Impl* impl) { return impl->empty(); }
static size_t Size(Impl* impl) { return impl->size(); }
static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
static Iterator Begin(Impl* impl) { return impl->begin(); }
static Iterator End(Impl* impl) { return impl->end(); }
static K Key(Iterator it) { return it->first; }
static PersistentContainerValue Value(Iterator it) { return it->second; }
static PersistentContainerValue Set(Impl* impl, K key,
PersistentContainerValue value) {
std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
PersistentContainerValue old_value = kPersistentContainerNotFound;
if (!res.second) {
old_value = res.first->second;
res.first->second = value;
}
return old_value;
}
static PersistentContainerValue Get(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
return it->second;
}
static PersistentContainerValue Remove(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
PersistentContainerValue value = it->second;
impl->erase(it);
return value;
}
};
/**
* A default trait implementation for PersistentValueMap, which inherits
* a std:map backing map from StdMapTraits and holds non-weak persistent
* objects and has no special Dispose handling.
*
* You should not derive from this class, since MapType depends on the
* surrounding class, and hence a subclass cannot simply inherit the methods.
*/
template<typename K, typename V>
class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(
MapType* map, const K& key, Local<V> value) {
return NULL;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return NULL;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) { }
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
};
template <typename K, typename V>
class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
private:
template <typename T>
struct RemovePointer;
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
Local<V> value) {
return nullptr;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return nullptr;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) {}
static void OnWeakCallback(
const WeakCallbackInfo<WeakCallbackDataType>& data) {}
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
// This is a second pass callback, so SetSecondPassCallback cannot be called.
static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {}
private:
template <typename T>
struct RemovePointer<T*> {
typedef T Type;
};
};
/**
* A map wrapper that allows using Global as a mapped value.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* The map relies on a backing map, whose type and accessors are described
* by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template <typename K, typename V, typename Traits>
class PersistentValueMapBase {
public:
Isolate* GetIsolate() { return isolate_; }
/**
* Return size of the map.
*/
size_t Size() { return Traits::Size(&impl_); }
/**
* Return whether the map holds weak persistents.
*/
bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
/**
* Get value stored in map.
*/
Local<V> Get(const K& key) {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
}
/**
* Check whether a value is contained in the map.
*/
bool Contains(const K& key) {
return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
}
/**
* Get value stored in map and set it in returnValue.
* Return true if a value was found.
*/
bool SetReturnValue(const K& key,
ReturnValue<Value> returnValue) {
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
* key.
*/
void RegisterExternallyReferencedObject(K& key) {
assert(Contains(key));
V8::RegisterExternallyReferencedObject(
reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Isolate*>(GetIsolate()));
}
/**
* Return value for key and remove it from the map.
*/
Global<V> Remove(const K& key) {
return Release(Traits::Remove(&impl_, key)).Pass();
}
/**
* Traverses the map repeatedly,
* in case side effects of disposal cause insertions.
**/
void Clear() {
typedef typename Traits::Iterator It;
HandleScope handle_scope(isolate_);
// TODO(dcarney): figure out if this swap and loop is necessary.
while (!Traits::Empty(&impl_)) {
typename Traits::Impl impl;
Traits::Swap(impl_, impl);
for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
Traits::Key(i));
}
}
}
/**
* Helper class for GetReference/SetWithReference. Do not use outside
* that context.
*/
class PersistentValueReference {
public:
PersistentValueReference() : value_(kPersistentContainerNotFound) { }
PersistentValueReference(const PersistentValueReference& other)
: value_(other.value_) { }
Local<V> NewLocal(Isolate* isolate) const {
return Local<V>::New(isolate, FromVal(value_));
}
bool IsEmpty() const {
return value_ == kPersistentContainerNotFound;
}
template<typename T>
bool SetReturnValue(ReturnValue<T> returnValue) {
return SetReturnValueFromVal(&returnValue, value_);
}
void Reset() {
value_ = kPersistentContainerNotFound;
}
void operator=(const PersistentValueReference& other) {
value_ = other.value_;
}
private:
friend class PersistentValueMapBase;
friend class PersistentValueMap<K, V, Traits>;
friend class GlobalValueMap<K, V, Traits>;
explicit PersistentValueReference(PersistentContainerValue value)
: value_(value) { }
void operator=(PersistentContainerValue value) {
value_ = value;
}
PersistentContainerValue value_;
};
/**
* Get a reference to a map value. This enables fast, repeated access
* to a value stored in the map while the map remains unchanged.
*
* Careful: This is potentially unsafe, so please use with care.
* The value will become invalid if the value for this key changes
* in the underlying map, as a result of Set or Remove for the same
* key; as a result of the weak callback for the same key; or as a
* result of calling Clear() or destruction of the map.
*/
PersistentValueReference GetReference(const K& key) {
return PersistentValueReference(Traits::Get(&impl_, key));
}
protected:
explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
~PersistentValueMapBase() { Clear(); }
Isolate* isolate() { return isolate_; }
typename Traits::Impl* impl() { return &impl_; }
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static PersistentContainerValue Leak(Global<V>* persistent) {
return reinterpret_cast<PersistentContainerValue>(persistent->val_);
}
/**
* Return a container value as Global and make sure the weak
* callback is properly disposed of. All remove functionality should go
* through this.
*/
static Global<V> Release(PersistentContainerValue v) {
Global<V> p;
p.val_ = FromVal(v);
if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
Traits::DisposeCallbackData(
p.template ClearWeak<typename Traits::WeakCallbackDataType>());
}
return p.Pass();
}
void RemoveWeak(const K& key) {
Global<V> p;
p.val_ = FromVal(Traits::Remove(&impl_, key));
p.Reset();
}
private:
PersistentValueMapBase(PersistentValueMapBase&);
void operator=(PersistentValueMapBase&);
static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
PersistentContainerValue value) {
bool hasValue = value != kPersistentContainerNotFound;
if (hasValue) {
returnValue->SetInternal(
*reinterpret_cast<internal::Object**>(FromVal(value)));
}
return hasValue;
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
template <typename K, typename V, typename Traits>
class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit PersistentValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), WeakCallback);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void WeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
PersistentValueMap<K, V, Traits>* persistentValueMap =
Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
Traits::Dispose(data.GetIsolate(),
persistentValueMap->Remove(key).Pass(), key);
Traits::DisposeCallbackData(data.GetParameter());
}
}
};
template <typename K, typename V, typename Traits>
class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit GlobalValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
WeakCallbackType callback_type =
Traits::kCallbackType == kWeakWithInternalFields
? WeakCallbackType::kInternalFields
: WeakCallbackType::kParameter;
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
callback_type);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void OnWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
auto map = Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
map->RemoveWeak(key);
Traits::OnWeakCallback(data);
data.SetSecondPassCallback(SecondWeakCallback);
}
}
static void SecondWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
Traits::DisposeWeak(data);
}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Persistents are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template<typename K, typename V,
typename Traits = DefaultPersistentValueMapTraits<K, V> >
class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
public:
explicit StdPersistentValueMap(Isolate* isolate)
: PersistentValueMap<K, V, Traits>(isolate) {}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Globals are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template <typename K, typename V,
typename Traits = DefaultGlobalMapTraits<K, V> >
class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
public:
explicit StdGlobalValueMap(Isolate* isolate)
: GlobalValueMap<K, V, Traits>(isolate) {}
};
class DefaultPersistentValueVectorTraits {
public:
typedef std::vector<PersistentContainerValue> Impl;
static void Append(Impl* impl, PersistentContainerValue value) {
impl->push_back(value);
}
static bool IsEmpty(const Impl* impl) {
return impl->empty();
}
static size_t Size(const Impl* impl) {
return impl->size();
}
static PersistentContainerValue Get(const Impl* impl, size_t i) {
return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
}
static void ReserveCapacity(Impl* impl, size_t capacity) {
impl->reserve(capacity);
}
static void Clear(Impl* impl) {
impl->clear();
}
};
/**
* A vector wrapper that safely stores Global values.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* This class relies on a backing vector implementation, whose type and methods
* are described by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
class PersistentValueVector {
public:
explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
~PersistentValueVector() {
Clear();
}
/**
* Append a value to the vector.
*/
void Append(Local<V> value) {
Global<V> persistent(isolate_, value);
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Append a persistent's value to the vector.
*/
void Append(Global<V> persistent) {
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Are there any values in the vector?
*/
bool IsEmpty() const {
return Traits::IsEmpty(&impl_);
}
/**
* How many elements are in the vector?
*/
size_t Size() const {
return Traits::Size(&impl_);
}
/**
* Retrieve the i-th value in the vector.
*/
Local<V> Get(size_t index) const {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
}
/**
* Remove all elements from the vector.
*/
void Clear() {
size_t length = Traits::Size(&impl_);
for (size_t i = 0; i < length; i++) {
Global<V> p;
p.val_ = FromVal(Traits::Get(&impl_, i));
}
Traits::Clear(&impl_);
}
/**
* Reserve capacity in the vector.
* (Efficiency gains depend on the backing implementation.)
*/
void ReserveCapacity(size_t capacity) {
Traits::ReserveCapacity(&impl_, capacity);
}
private:
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
} // namespace v8
#endif // V8_UTIL_H

View File

@ -0,0 +1,24 @@
// Copyright 2017 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.
/**
* Compile-time constants.
*
* This header provides access to information about the value serializer at
* compile time, without declaring or defining any symbols that require linking
* to V8.
*/
#ifndef INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#define INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#include <stdint.h>
namespace v8 {
constexpr uint32_t CurrentValueSerializerFormatVersion() { return 13; }
} // namespace v8
#endif // INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_

View File

@ -0,0 +1,33 @@
// Copyright 2017 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_VERSION_STRING_H_
#define V8_VERSION_STRING_H_
#include "v8-version.h" // NOLINT(build/include)
// This is here rather than v8-version.h to keep that file simple and
// machine-processable.
#if V8_IS_CANDIDATE_VERSION
#define V8_CANDIDATE_STRING " (candidate)"
#else
#define V8_CANDIDATE_STRING ""
#endif
#define V8_SX(x) #x
#define V8_S(x) V8_SX(x)
#if V8_PATCH_LEVEL > 0
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \
V8_PATCH_LEVEL) V8_CANDIDATE_STRING
#else
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) V8_CANDIDATE_STRING
#endif
#endif // V8_VERSION_STRING_H_

View File

@ -0,0 +1,20 @@
// Copyright 2015 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_INCLUDE_VERSION_H_ // V8_VERSION_H_ conflicts with src/version.h
#define V8_INCLUDE_VERSION_H_
// These macros define the version number for the current version.
// 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.
#define V8_MAJOR_VERSION 6
#define V8_MINOR_VERSION 0
#define V8_BUILD_NUMBER 286
#define V8_PATCH_LEVEL 52
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define V8_IS_CANDIDATE_VERSION 0
#endif // V8_INCLUDE_VERSION_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,428 @@
// Copyright 2013 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 V8CONFIG_H_
#define V8CONFIG_H_
// clang-format off
// Platform headers for feature detection below.
#if defined(__ANDROID__)
# include <sys/cdefs.h>
#elif defined(__APPLE__)
# include <TargetConditionals.h>
#elif defined(__linux__)
# include <features.h>
#endif
// This macro allows to test for the version of the GNU C library (or
// a compatible C library that masquerades as glibc). It evaluates to
// 0 if libc is not GNU libc or compatible.
// Use like:
// #if V8_GLIBC_PREREQ(2, 3)
// ...
// #endif
#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
# define V8_GLIBC_PREREQ(major, minor) \
((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor)))
#else
# define V8_GLIBC_PREREQ(major, minor) 0
#endif
// This macro allows to test for the version of the GNU C++ compiler.
// Note that this also applies to compilers that masquerade as GCC,
// for example clang and the Intel C++ compiler for Linux.
// Use like:
// #if V8_GNUC_PREREQ(4, 3, 1)
// ...
// #endif
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#else
# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
#endif
// -----------------------------------------------------------------------------
// Operating system detection
//
// V8_OS_ANDROID - Android
// V8_OS_BSD - BSDish (Mac OS X, Net/Free/Open/DragonFlyBSD)
// V8_OS_CYGWIN - Cygwin
// V8_OS_DRAGONFLYBSD - DragonFlyBSD
// V8_OS_FREEBSD - FreeBSD
// V8_OS_LINUX - Linux
// V8_OS_MACOSX - Mac OS X
// V8_OS_NETBSD - NetBSD
// V8_OS_OPENBSD - OpenBSD
// V8_OS_POSIX - POSIX compatible (mostly everything except Windows)
// V8_OS_QNX - QNX Neutrino
// V8_OS_SOLARIS - Sun Solaris and OpenSolaris
// V8_OS_AIX - AIX
// V8_OS_WIN - Microsoft Windows
#if defined(__ANDROID__)
# define V8_OS_ANDROID 1
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__APPLE__)
# define V8_OS_BSD 1
# define V8_OS_MACOSX 1
# define V8_OS_POSIX 1
#elif defined(__CYGWIN__)
# define V8_OS_CYGWIN 1
# define V8_OS_POSIX 1
#elif defined(__linux__)
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__sun)
# define V8_OS_POSIX 1
# define V8_OS_SOLARIS 1
#elif defined(_AIX)
#define V8_OS_POSIX 1
#define V8_OS_AIX 1
#elif defined(__FreeBSD__)
# define V8_OS_BSD 1
# define V8_OS_FREEBSD 1
# define V8_OS_POSIX 1
#elif defined(__DragonFly__)
# define V8_OS_BSD 1
# define V8_OS_DRAGONFLYBSD 1
# define V8_OS_POSIX 1
#elif defined(__NetBSD__)
# define V8_OS_BSD 1
# define V8_OS_NETBSD 1
# define V8_OS_POSIX 1
#elif defined(__OpenBSD__)
# define V8_OS_BSD 1
# define V8_OS_OPENBSD 1
# define V8_OS_POSIX 1
#elif defined(__QNXNTO__)
# define V8_OS_POSIX 1
# define V8_OS_QNX 1
#elif defined(_WIN32)
# define V8_OS_WIN 1
#endif
// -----------------------------------------------------------------------------
// C library detection
//
// V8_LIBC_MSVCRT - MSVC libc
// V8_LIBC_BIONIC - Bionic libc
// V8_LIBC_BSD - BSD libc derivate
// V8_LIBC_GLIBC - GNU C library
// V8_LIBC_UCLIBC - uClibc
//
// Note that testing for libc must be done using #if not #ifdef. For example,
// to test for the GNU C library, use:
// #if V8_LIBC_GLIBC
// ...
// #endif
#if defined (_MSC_VER)
# define V8_LIBC_MSVCRT 1
#elif defined(__BIONIC__)
# define V8_LIBC_BIONIC 1
# define V8_LIBC_BSD 1
#elif defined(__UCLIBC__)
// Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC.
# define V8_LIBC_UCLIBC 1
#elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
# define V8_LIBC_GLIBC 1
#else
# define V8_LIBC_BSD V8_OS_BSD
#endif
// -----------------------------------------------------------------------------
// Compiler detection
//
// V8_CC_GNU - GCC, or clang in gcc mode
// V8_CC_INTEL - Intel C++
// V8_CC_MINGW - Minimalist GNU for Windows
// V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
// V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
// V8_CC_MSVC - Microsoft Visual C/C++, or clang in cl.exe mode
//
// C++11 feature detection
//
// V8_HAS_CXX11_ALIGNAS - alignas specifier supported
// V8_HAS_CXX11_ALIGNOF - alignof(type) operator supported
//
// 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))
// supported
// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) 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_VISIBILITY - __attribute__((visibility)) supported
// V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
// supported
// V8_HAS_BUILTIN_CLZ - __builtin_clz() supported
// V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported
// V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported
// V8_HAS_BUILTIN_FRAME_ADDRESS - __builtin_frame_address() supported
// V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported
// V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported
// V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_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_NOINLINE - __declspec(noinline) supported
// V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported
// V8_HAS_DECLSPEC_NORETURN - __declspec(noreturn) supported
// V8_HAS___FORCEINLINE - __forceinline supported
//
// Note that testing for compilers and/or features must be done using #if
// not #ifdef. For example, to test for Intel C++ Compiler, use:
// #if V8_CC_INTEL
// ...
// #endif
#if defined(__clang__)
#if defined(__GNUC__) // Clang in gcc mode.
# define V8_CC_GNU 1
#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_DEPRECATED (__has_attribute(deprecated))
# 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_VISIBILITY (__has_attribute(visibility))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(__has_attribute(warn_unused_result))
# define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
# define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
# define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address))
# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
# define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_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_CXX11_ALIGNAS (__has_feature(cxx_alignas))
#elif defined(__GNUC__)
# define V8_CC_GNU 1
# if defined(__INTEL_COMPILER) // Intel C++ also masquerades as GCC 3.2.0
# define V8_CC_INTEL 1
# endif
# if defined(__MINGW32__)
# define V8_CC_MINGW32 1
# endif
# if defined(__MINGW64__)
# define V8_CC_MINGW64 1
# endif
# 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.
// Works around "sorry, unimplemented: inlining failed" build errors with
// older compilers.
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 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_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_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
# define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_EXPECT (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))
# 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
#if defined(_MSC_VER)
# 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_NOINLINE 1
# define V8_HAS_DECLSPEC_SELECTANY 1
# define V8_HAS_DECLSPEC_NORETURN 1
# define V8_HAS___FORCEINLINE 1
#endif
// -----------------------------------------------------------------------------
// Helper macros
// A macro used to make better inlining. Don't bother for debug builds.
// Use like:
// V8_INLINE int GetZero() { return 0; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
# define V8_INLINE inline __attribute__((always_inline))
#elif !defined(DEBUG) && V8_HAS___FORCEINLINE
# define V8_INLINE __forceinline
#else
# define V8_INLINE inline
#endif
// A macro used to tell the compiler to never inline a particular function.
// Don't bother for debug builds.
// Use like:
// V8_NOINLINE int GetMinusOne() { return -1; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
# define V8_NOINLINE __attribute__((noinline))
#elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
# define V8_NOINLINE __declspec(noinline)
#else
# define V8_NOINLINE /* NOT SUPPORTED */
#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.
#if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATED(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATED(message, declarator) declarator
#endif
// A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated.
#if defined(V8_IMMINENT_DEPRECATION_WARNINGS) && \
V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATE_SOON(message, declarator) declarator
#endif
// A macro to provide the compiler with branch prediction information.
#if V8_HAS_BUILTIN_EXPECT
# define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
# define V8_LIKELY(condition) (__builtin_expect(!!(condition), 1))
#else
# define V8_UNLIKELY(condition) (condition)
# define V8_LIKELY(condition) (condition)
#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.
// Use like:
// int foo() WARN_UNUSED_RESULT;
#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
#endif
// clang-format on
#endif // V8CONFIG_H_

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,29 @@
// Copyright 2016 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_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#if defined(_WIN32)
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllexport)
#elif USING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllimport)
#else
#define V8_PLATFORM_EXPORT
#endif // BUILDING_V8_PLATFORM_SHARED
#else // defined(_WIN32)
// Setup for Linux shared library export.
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __attribute__((visibility("default")))
#else
#define V8_PLATFORM_EXPORT
#endif
#endif // defined(_WIN32)
#endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_

View File

@ -0,0 +1,78 @@
// Copyright 2014 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_LIBPLATFORM_LIBPLATFORM_H_
#define V8_LIBPLATFORM_LIBPLATFORM_H_
#include "libplatform/libplatform-export.h"
#include "libplatform/v8-tracing.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace platform {
enum class IdleTaskSupport { kDisabled, kEnabled };
enum class InProcessStackDumping { kDisabled, kEnabled };
enum class MessageLoopBehavior : bool {
kDoNotWait = false,
kWaitForWork = true
};
/**
* Returns a new instance of the default v8::Platform implementation.
*
* The caller will take ownership of the returned pointer. |thread_pool_size|
* is the number of worker threads to allocate for background jobs. If a value
* of zero is passed, a suitable default based on the current number of
* processors online will be chosen.
* If |idle_task_support| is enabled then the platform will accept idle
* tasks (IdleTasksEnabled will return true) and will rely on the embedder
* calling v8::platform::RunIdleTasks to process the idle tasks.
*/
V8_PLATFORM_EXPORT v8::Platform* CreateDefaultPlatform(
int thread_pool_size = 0,
IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
InProcessStackDumping in_process_stack_dumping =
InProcessStackDumping::kEnabled);
/**
* Pumps the message loop for the given isolate.
*
* 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
* through the |behavior| parameter, this call does not block if no task is
* pending. The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT bool PumpMessageLoop(
v8::Platform* platform, v8::Isolate* isolate,
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.
*
* 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
* created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
v8::Isolate* isolate,
double idle_time_in_seconds);
/**
* Attempts to set the tracing controller for the given platform.
*
* The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void SetTracingController(
v8::Platform* platform,
v8::platform::tracing::TracingController* tracing_controller);
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_LIBPLATFORM_H_

View File

@ -0,0 +1,270 @@
// Copyright 2016 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_LIBPLATFORM_V8_TRACING_H_
#define V8_LIBPLATFORM_V8_TRACING_H_
#include <fstream>
#include <memory>
#include <unordered_set>
#include <vector>
#include "libplatform/libplatform-export.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace base {
class Mutex;
} // namespace base
namespace platform {
namespace tracing {
const int kTraceMaxNumArgs = 2;
class V8_PLATFORM_EXPORT TraceObject {
public:
union ArgValue {
bool as_bool;
uint64_t as_uint;
int64_t as_int;
double as_double;
const void* as_pointer;
const char* as_string;
};
TraceObject() {}
~TraceObject();
void Initialize(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateDuration();
void InitializeForTesting(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
uint64_t duration, uint64_t cpu_duration);
int pid() const { return pid_; }
int tid() const { return tid_; }
char phase() const { return phase_; }
const uint8_t* category_enabled_flag() const {
return category_enabled_flag_;
}
const char* name() const { return name_; }
const char* scope() const { return scope_; }
uint64_t id() const { return id_; }
uint64_t bind_id() const { return bind_id_; }
int num_args() const { return num_args_; }
const char** arg_names() { return arg_names_; }
uint8_t* arg_types() { return arg_types_; }
ArgValue* arg_values() { return arg_values_; }
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables() {
return arg_convertables_;
}
unsigned int flags() const { return flags_; }
int64_t ts() { return ts_; }
int64_t tts() { return tts_; }
uint64_t duration() { return duration_; }
uint64_t cpu_duration() { return cpu_duration_; }
private:
int pid_;
int tid_;
char phase_;
const char* name_;
const char* scope_;
const uint8_t* category_enabled_flag_;
uint64_t id_;
uint64_t bind_id_;
int num_args_ = 0;
const char* arg_names_[kTraceMaxNumArgs];
uint8_t arg_types_[kTraceMaxNumArgs];
ArgValue arg_values_[kTraceMaxNumArgs];
std::unique_ptr<v8::ConvertableToTraceFormat>
arg_convertables_[kTraceMaxNumArgs];
char* parameter_copy_storage_ = nullptr;
unsigned int flags_;
int64_t ts_;
int64_t tts_;
uint64_t duration_;
uint64_t cpu_duration_;
// Disallow copy and assign
TraceObject(const TraceObject&) = delete;
void operator=(const TraceObject&) = delete;
};
class V8_PLATFORM_EXPORT TraceWriter {
public:
TraceWriter() {}
virtual ~TraceWriter() {}
virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
virtual void Flush() = 0;
static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
private:
// Disallow copy and assign
TraceWriter(const TraceWriter&) = delete;
void operator=(const TraceWriter&) = delete;
};
class V8_PLATFORM_EXPORT TraceBufferChunk {
public:
explicit TraceBufferChunk(uint32_t seq);
void Reset(uint32_t new_seq);
bool IsFull() const { return next_free_ == kChunkSize; }
TraceObject* AddTraceEvent(size_t* event_index);
TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
uint32_t seq() const { return seq_; }
size_t size() const { return next_free_; }
static const size_t kChunkSize = 64;
private:
size_t next_free_ = 0;
TraceObject chunk_[kChunkSize];
uint32_t seq_;
// Disallow copy and assign
TraceBufferChunk(const TraceBufferChunk&) = delete;
void operator=(const TraceBufferChunk&) = delete;
};
class V8_PLATFORM_EXPORT TraceBuffer {
public:
TraceBuffer() {}
virtual ~TraceBuffer() {}
virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
virtual bool Flush() = 0;
static const size_t kRingBufferChunks = 1024;
static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
TraceWriter* trace_writer);
private:
// Disallow copy and assign
TraceBuffer(const TraceBuffer&) = delete;
void operator=(const TraceBuffer&) = delete;
};
// Options determines how the trace buffer stores data.
enum TraceRecordMode {
// Record until the trace buffer is full.
RECORD_UNTIL_FULL,
// Record until the user ends the trace. The trace buffer is a fixed size
// and we use it as a ring buffer during recording.
RECORD_CONTINUOUSLY,
// Record until the trace buffer is full, but with a huge buffer size.
RECORD_AS_MUCH_AS_POSSIBLE,
// Echo to console. Events are discarded.
ECHO_TO_CONSOLE,
};
class V8_PLATFORM_EXPORT TraceConfig {
public:
typedef std::vector<std::string> StringList;
static TraceConfig* CreateDefaultTraceConfig();
TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
bool IsSystraceEnabled() const { return enable_systrace_; }
bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
void EnableSystrace() { enable_systrace_ = true; }
void EnableArgumentFilter() { enable_argument_filter_ = true; }
void AddIncludedCategory(const char* included_category);
bool IsCategoryGroupEnabled(const char* category_group) const;
private:
TraceRecordMode record_mode_;
bool enable_systrace_ : 1;
bool enable_argument_filter_ : 1;
StringList included_categories_;
// Disallow copy and assign
TraceConfig(const TraceConfig&) = delete;
void operator=(const TraceConfig&) = delete;
};
class V8_PLATFORM_EXPORT TracingController {
public:
enum Mode { DISABLED = 0, RECORDING_MODE };
// The pointer returned from GetCategoryGroupEnabledInternal() 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 {
// Category group enabled for the recording mode.
ENABLED_FOR_RECORDING = 1 << 0,
// Category group enabled by SetEventCallbackEnabled().
ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
// Category group enabled to export events to ETW.
ENABLED_FOR_ETW_EXPORT = 1 << 3
};
TracingController();
~TracingController();
void Initialize(TraceBuffer* trace_buffer);
const uint8_t* GetCategoryGroupEnabled(const char* category_group);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle);
void StartTracing(TraceConfig* trace_config);
void StopTracing();
void AddTraceStateObserver(Platform::TraceStateObserver* observer);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
void UpdateCategoryGroupEnabledFlag(size_t category_index);
void UpdateCategoryGroupEnabledFlags();
std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_;
Mode mode_ = DISABLED;
// Disallow copy and assign
TracingController(const TracingController&) = delete;
void operator=(const TracingController&) = delete;
};
} // namespace tracing
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_V8_TRACING_H_

View File

@ -0,0 +1,255 @@
// 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

@ -0,0 +1,13 @@
// Copyright 2016 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_INSPECTOR_PROTOCOL_H_
#define V8_V8_INSPECTOR_PROTOCOL_H_
#include "inspector/Debugger.h" // NOLINT(build/include)
#include "inspector/Runtime.h" // NOLINT(build/include)
#include "inspector/Schema.h" // NOLINT(build/include)
#include "v8-inspector.h" // NOLINT(build/include)
#endif // V8_V8_INSPECTOR_PROTOCOL_H_

View File

@ -0,0 +1,267 @@
// Copyright 2016 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_INSPECTOR_H_
#define V8_V8_INSPECTOR_H_
#include <stdint.h>
#include <cctype>
#include <memory>
#include "v8.h" // NOLINT(build/include)
namespace v8_inspector {
namespace protocol {
namespace Debugger {
namespace API {
class SearchMatch;
}
}
namespace Runtime {
namespace API {
class RemoteObject;
class StackTrace;
}
}
namespace Schema {
namespace API {
class Domain;
}
}
} // namespace protocol
class V8_EXPORT StringView {
public:
StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {}
StringView(const uint8_t* characters, size_t length)
: m_is8Bit(true), m_length(length), m_characters8(characters) {}
StringView(const uint16_t* characters, size_t length)
: m_is8Bit(false), m_length(length), m_characters16(characters) {}
bool is8Bit() const { return m_is8Bit; }
size_t length() const { return m_length; }
// TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used
// here.
const uint8_t* characters8() const { return m_characters8; }
const uint16_t* characters16() const { return m_characters16; }
private:
bool m_is8Bit;
size_t m_length;
union {
const uint8_t* m_characters8;
const uint16_t* m_characters16;
};
};
class V8_EXPORT StringBuffer {
public:
virtual ~StringBuffer() {}
virtual const StringView& string() = 0;
// This method copies contents.
static std::unique_ptr<StringBuffer> create(const StringView&);
};
class V8_EXPORT V8ContextInfo {
public:
V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId,
const StringView& humanReadableName)
: context(context),
contextGroupId(contextGroupId),
humanReadableName(humanReadableName),
hasMemoryOnConsole(false) {}
v8::Local<v8::Context> context;
// Each v8::Context is a part of a group. The group id must be non-zero.
int contextGroupId;
StringView humanReadableName;
StringView origin;
StringView auxData;
bool hasMemoryOnConsole;
static int executionContextId(v8::Local<v8::Context> context);
private:
// Disallow copying and allocating this one.
enum NotNullTagEnum { NotNullLiteral };
void* operator new(size_t) = delete;
void* operator new(size_t, NotNullTagEnum, void*) = delete;
void* operator new(size_t, void*) = delete;
V8ContextInfo(const V8ContextInfo&) = delete;
V8ContextInfo& operator=(const V8ContextInfo&) = delete;
};
class V8_EXPORT V8StackTrace {
public:
virtual bool isEmpty() const = 0;
virtual StringView topSourceURL() const = 0;
virtual int topLineNumber() const = 0;
virtual int topColumnNumber() const = 0;
virtual StringView topScriptId() const = 0;
virtual StringView topFunctionName() const = 0;
virtual ~V8StackTrace() {}
virtual std::unique_ptr<protocol::Runtime::API::StackTrace>
buildInspectorObject() const = 0;
virtual std::unique_ptr<StringBuffer> toString() const = 0;
// Safe to pass between threads, drops async chain.
virtual std::unique_ptr<V8StackTrace> clone() = 0;
};
class V8_EXPORT V8InspectorSession {
public:
virtual ~V8InspectorSession() {}
// Cross-context inspectable values (DOM nodes in different worlds, etc.).
class V8_EXPORT Inspectable {
public:
virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0;
virtual ~Inspectable() {}
};
virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0;
// Dispatching protocol messages.
static bool canDispatchMethod(const StringView& method);
virtual void dispatchProtocolMessage(const StringView& message) = 0;
virtual std::unique_ptr<StringBuffer> stateJSON() = 0;
virtual std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
supportedDomains() = 0;
// Debugger actions.
virtual void schedulePauseOnNextStatement(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void cancelPauseOnNextStatement() = 0;
virtual void breakProgram(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void setSkipAllPauses(bool) = 0;
virtual void resume() = 0;
virtual void stepOver() = 0;
virtual std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
searchInTextByLines(const StringView& text, const StringView& query,
bool caseSensitive, bool isRegex) = 0;
// Remote objects.
virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject(
v8::Local<v8::Context>, v8::Local<v8::Value>,
const StringView& groupName) = 0;
virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error,
const StringView& objectId, v8::Local<v8::Value>*,
v8::Local<v8::Context>*,
std::unique_ptr<StringBuffer>* objectGroup) = 0;
virtual void releaseObjectGroup(const StringView&) = 0;
};
class V8_EXPORT V8InspectorClient {
public:
virtual ~V8InspectorClient() {}
virtual void runMessageLoopOnPause(int contextGroupId) {}
virtual void quitMessageLoopOnPause() {}
virtual void runIfWaitingForDebugger(int contextGroupId) {}
virtual void muteMetrics(int contextGroupId) {}
virtual void unmuteMetrics(int contextGroupId) {}
virtual void beginUserGesture() {}
virtual void endUserGesture() {}
virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) {
return nullptr;
}
virtual bool formatAccessorsAsProperties(v8::Local<v8::Value>) {
return false;
}
virtual bool isInspectableHeapObject(v8::Local<v8::Object>) { return true; }
virtual v8::Local<v8::Context> ensureDefaultContextInGroup(
int contextGroupId) {
return v8::Local<v8::Context>();
}
virtual void beginEnsureAllContextsInGroup(int contextGroupId) {}
virtual void endEnsureAllContextsInGroup(int contextGroupId) {}
virtual void installAdditionalCommandLineAPI(v8::Local<v8::Context>,
v8::Local<v8::Object>) {}
virtual void consoleAPIMessage(int contextGroupId,
v8::Isolate::MessageErrorLevel level,
const StringView& message,
const StringView& url, unsigned lineNumber,
unsigned columnNumber, V8StackTrace*) {}
virtual v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*,
v8::Local<v8::Context>) {
return v8::MaybeLocal<v8::Value>();
}
virtual void consoleTime(const StringView& title) {}
virtual void consoleTimeEnd(const StringView& title) {}
virtual void consoleTimeStamp(const StringView& title) {}
virtual void consoleClear(int contextGroupId) {}
virtual double currentTimeMS() { return 0; }
typedef void (*TimerCallback)(void*);
virtual void startRepeatingTimer(double, TimerCallback, void* data) {}
virtual void cancelTimer(void* data) {}
// TODO(dgozman): this was added to support service worker shadow page. We
// should not connect at all.
virtual bool canExecuteScripts(int contextGroupId) { return true; }
};
class V8_EXPORT V8Inspector {
public:
static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*);
virtual ~V8Inspector() {}
// Contexts instrumentation.
virtual void contextCreated(const V8ContextInfo&) = 0;
virtual void contextDestroyed(v8::Local<v8::Context>) = 0;
virtual void resetContextGroup(int contextGroupId) = 0;
// Various instrumentation.
virtual void idleStarted() = 0;
virtual void idleFinished() = 0;
// Async stack traces instrumentation.
virtual void asyncTaskScheduled(const StringView& taskName, void* task,
bool recurring) = 0;
virtual void asyncTaskCanceled(void* task) = 0;
virtual void asyncTaskStarted(void* task) = 0;
virtual void asyncTaskFinished(void* task) = 0;
virtual void allAsyncTasksCanceled() = 0;
// Exceptions instrumentation.
virtual unsigned exceptionThrown(
v8::Local<v8::Context>, const StringView& message,
v8::Local<v8::Value> exception, const StringView& detailedMessage,
const StringView& url, unsigned lineNumber, unsigned columnNumber,
std::unique_ptr<V8StackTrace>, int scriptId) = 0;
virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId,
const StringView& message) = 0;
// Connection.
class V8_EXPORT Channel {
public:
virtual ~Channel() {}
virtual void sendResponse(int callId,
std::unique_ptr<StringBuffer> message) = 0;
virtual void sendNotification(std::unique_ptr<StringBuffer> message) = 0;
virtual void flushProtocolNotifications() = 0;
};
virtual std::unique_ptr<V8InspectorSession> connect(
int contextGroupId, Channel*, const StringView& state) = 0;
// API methods.
virtual std::unique_ptr<V8StackTrace> createStackTrace(
v8::Local<v8::StackTrace>) = 0;
virtual std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) = 0;
};
} // namespace v8_inspector
#endif // V8_V8_INSPECTOR_H_

View File

@ -0,0 +1,227 @@
// Copyright 2013 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_PLATFORM_H_
#define V8_V8_PLATFORM_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
namespace v8 {
class Isolate;
/**
* A Task represents a unit of work.
*/
class Task {
public:
virtual ~Task() = default;
virtual void Run() = 0;
};
/**
* An IdleTask represents a unit of work to be performed in idle time.
* The Run method is invoked with an argument that specifies the deadline in
* seconds returned by MonotonicallyIncreasingTime().
* The idle task is expected to complete by this deadline.
*/
class IdleTask {
public:
virtual ~IdleTask() = default;
virtual void Run(double deadline_in_seconds) = 0;
};
/**
* The interface represents complex arguments to trace events.
*/
class ConvertableToTraceFormat {
public:
virtual ~ConvertableToTraceFormat() = default;
/**
* Append the class info to the provided |out| string. The appended
* data must be a valid JSON object. Strings must be properly quoted, and
* escaped. There is no processing applied to the content after it is
* appended.
*/
virtual void AppendAsTraceFormat(std::string* out) const = 0;
};
/**
* V8 Platform abstraction layer.
*
* The embedder has to provide an implementation of this interface before
* initializing the rest of V8.
*/
class Platform {
public:
/**
* 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.
* The name parameter is a category group for example:
* TRACE_EVENT0("v8,parse", "V8.Parse")
* The pointer returned points to a value with zero or more of the bits
* defined in CategoryGroupEnabledFlags.
**/
virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
static uint8_t no = 0;
return &no;
}
/**
* Gets the category group name of the given category_enabled_flag pointer.
* 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
* tracing and the category of the particular trace are enabled. It is not
* advisable to call this function on its own; it is really only meant to be
* used by the trace macros. The returned handle can be used by
* UpdateTraceEventDuration to update the duration of COMPLETE events.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values, 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.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) {
return AddTraceEvent(phase, category_enabled_flag, name, scope, id, bind_id,
num_args, arg_names, arg_types, arg_values, flags);
}
/**
* Sets the duration field of a COMPLETE trace event. It must be called with
* the handle returned from AddTraceEvent().
**/
virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {}
class TraceStateObserver {
public:
virtual ~TraceStateObserver() = default;
virtual void OnTraceEnabled() = 0;
virtual void OnTraceDisabled() = 0;
};
/** Adds tracing state change observer. */
virtual void AddTraceStateObserver(TraceStateObserver*) {}
/** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
typedef void (*StackTracePrinter)();
/**
* Returns a function pointer that print a stack trace of the current stack
* on invocation. Disables printing of the stack trace if nullptr.
*/
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
};
} // namespace v8
#endif // V8_V8_PLATFORM_H_

View File

@ -0,0 +1,912 @@
// Copyright 2010 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_PROFILER_H_
#define V8_V8_PROFILER_H_
#include <unordered_set>
#include <vector>
#include "v8.h" // NOLINT(build/include)
/**
* Profiler support for the V8 JavaScript engine.
*/
namespace v8 {
class HeapGraphNode;
struct HeapStatsUpdate;
typedef uint32_t SnapshotObjectId;
struct CpuProfileDeoptFrame {
int script_id;
size_t position;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
#endif
namespace v8 {
struct V8_EXPORT CpuProfileDeoptInfo {
/** A pointer to a static string owned by v8. */
const char* deopt_reason;
std::vector<CpuProfileDeoptFrame> stack;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
#endif
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.
struct TickSample {
// Internal profiling (with --prof + tools/$OS-tick-processor) wants to
// include the runtime function we're calling. Externally exposed tick
// samples don't care.
enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
TickSample()
: state(OTHER),
pc(nullptr),
external_callback_entry(nullptr),
frames_count(0),
has_external_callback(false),
update_stats(true) {}
/**
* Initialize a tick sample from the isolate.
* \param isolate The isolate.
* \param state Execution state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param update_stats Whether update the sample to the aggregated stats.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
*/
void Init(Isolate* isolate, const v8::RegisterState& state,
RecordCEntryFrame record_c_entry_frame, bool update_stats,
bool use_simulator_reg_state = true);
/**
* Get a call stack sample from the isolate.
* \param isolate The isolate.
* \param state Register state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param frames Caller allocated buffer to store stack frames.
* \param frames_limit Maximum number of frames to capture. The buffer must
* be large enough to hold the number of frames.
* \param sample_info The sample info is filled up by the function
* provides number of actual captured stack frames and
* the current VM state.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
* \note GetStackSample is thread and signal safe and should only be called
* when the JS thread is paused or interrupted.
* Otherwise the behavior is undefined.
*/
static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
RecordCEntryFrame record_c_entry_frame,
void** frames, size_t frames_limit,
v8::SampleInfo* sample_info,
bool use_simulator_reg_state = true);
StateTag state; // The state of the VM.
void* pc; // Instruction pointer.
union {
void* tos; // Top stack value (*sp).
void* external_callback_entry;
};
static const unsigned kMaxFramesCountLog2 = 8;
static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
void* stack[kMaxFramesCount]; // Call stack.
unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
bool has_external_callback : 1;
bool update_stats : 1; // Whether the sample should update aggregated stats.
};
/**
* CpuProfileNode represents a node in a call graph.
*/
class V8_EXPORT CpuProfileNode {
public:
struct LineTick {
/** The 1-based number of the source line where the function originates. */
int line;
/** The count of samples associated with the source line. */
unsigned int hit_count;
};
/** Returns function name (empty string for anonymous functions.) */
Local<String> GetFunctionName() const;
/**
* Returns function name (empty string for anonymous functions.)
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetFunctionNameStr() const;
/** Returns id of the script where function is located. */
int GetScriptId() const;
/** Returns resource name for script from where the function originates. */
Local<String> GetScriptResourceName() const;
/**
* Returns resource name for script from where the function originates.
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetScriptResourceNameStr() const;
/**
* Returns the number, 1-based, of the line where the function originates.
* kNoLineNumberInfo if no line number information is available.
*/
int GetLineNumber() const;
/**
* Returns 1-based number of the column where the function originates.
* kNoColumnNumberInfo if no column number information is available.
*/
int GetColumnNumber() const;
/**
* Returns the number of the function's source lines that collect the samples.
*/
unsigned int GetHitLineCount() const;
/** Returns the set of source lines that collect the samples.
* The caller allocates buffer and responsible for releasing it.
* True if all available entries are copied, otherwise false.
* The function copies nothing if buffer is not large enough.
*/
bool GetLineTicks(LineTick* entries, unsigned int length) const;
/** Returns bailout reason for the function
* if the optimization was disabled for it.
*/
const char* GetBailoutReason() const;
/**
* Returns the count of samples where the function was currently executing.
*/
unsigned GetHitCount() const;
/** Returns function entry UID. */
V8_DEPRECATE_SOON(
"Use GetScriptId, GetLineNumber, and GetColumnNumber instead.",
unsigned GetCallUid() const);
/** Returns id of the node. The id is unique within the tree */
unsigned GetNodeId() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child node by index. */
const CpuProfileNode* GetChild(int index) const;
/** Retrieves deopt infos for the node. */
const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* CpuProfile contains a CPU profile in a form of top-down call tree
* (from main() down to functions that do all the work).
*/
class V8_EXPORT CpuProfile {
public:
/** Returns CPU profile title. */
Local<String> GetTitle() const;
/** Returns the root node of the top down call tree. */
const CpuProfileNode* GetTopDownRoot() const;
/**
* Returns number of samples recorded. The samples are not recorded unless
* |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
*/
int GetSamplesCount() const;
/**
* Returns profile node corresponding to the top frame the sample at
* the given index.
*/
const CpuProfileNode* GetSample(int index) const;
/**
* Returns the timestamp of the sample. The timestamp is the number of
* microseconds since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetSampleTimestamp(int index) const;
/**
* Returns time when the profile recording was started (in microseconds)
* since some unspecified starting point.
*/
int64_t GetStartTime() const;
/**
* Returns time when the profile recording was stopped (in microseconds)
* since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetEndTime() const;
/**
* Deletes the profile and removes it from CpuProfiler's list.
* All pointers to nodes previously returned become invalid.
*/
void Delete();
};
/**
* Interface for controlling CPU profiling. Instance of the
* profiler can be created using v8::CpuProfiler::New method.
*/
class V8_EXPORT CpuProfiler {
public:
/**
* Creates a new CPU profiler for the |isolate|. The isolate must be
* initialized. The profiler object must be disposed after use by calling
* |Dispose| method.
*/
static CpuProfiler* New(Isolate* isolate);
/**
* Disposes the CPU profiler object.
*/
void Dispose();
/**
* Changes default CPU profiler sampling interval to the specified number
* of microseconds. Default interval is 1000us. This method must be called
* when there are no profiles being recorded.
*/
void SetSamplingInterval(int us);
/**
* Starts collecting CPU profile. Title may be an empty string. It
* is allowed to have several profiles being collected at
* once. Attempts to start collecting several profiles with the same
* title are silently ignored. While collecting a profile, functions
* from all security contexts are included in it. The token-based
* filtering is only performed when querying for a profile.
*
* |record_samples| parameter controls whether individual samples should
* be recorded in addition to the aggregated tree.
*/
void StartProfiling(Local<String> title, bool record_samples = false);
/**
* Stops collecting CPU profile with a given title and returns it.
* If the title given is empty, finishes the last profile started.
*/
CpuProfile* StopProfiling(Local<String> title);
/**
* Force collection of a sample. Must be called on the VM thread.
* Recording the forced sample does not contribute to the aggregated
* profile statistics.
*/
void CollectSample();
/**
* Tells the profiler whether the embedder is idle.
*/
void SetIdle(bool is_idle);
private:
CpuProfiler();
~CpuProfiler();
CpuProfiler(const CpuProfiler&);
CpuProfiler& operator=(const CpuProfiler&);
};
/**
* HeapSnapshotEdge represents a directed connection between heap
* graph nodes: from retainers to retained nodes.
*/
class V8_EXPORT HeapGraphEdge {
public:
enum Type {
kContextVariable = 0, // A variable from a function context.
kElement = 1, // An element of an array.
kProperty = 2, // A named object property.
kInternal = 3, // A link that can't be accessed from JS,
// thus, its name isn't a real property name
// (e.g. parts of a ConsString).
kHidden = 4, // A link that is needed for proper sizes
// calculation, but may be hidden from user.
kShortcut = 5, // A link that must not be followed during
// sizes calculation.
kWeak = 6 // A weak reference (ignored by the GC).
};
/** Returns edge type (see HeapGraphEdge::Type). */
Type GetType() const;
/**
* Returns edge name. This can be a variable name, an element index, or
* a property name.
*/
Local<Value> GetName() const;
/** Returns origin node. */
const HeapGraphNode* GetFromNode() const;
/** Returns destination node. */
const HeapGraphNode* GetToNode() const;
};
/**
* HeapGraphNode represents a node in a heap graph.
*/
class V8_EXPORT HeapGraphNode {
public:
enum Type {
kHidden = 0, // Hidden node, may be filtered when shown to user.
kArray = 1, // An array of elements.
kString = 2, // A string.
kObject = 3, // A JS object (except for arrays and strings).
kCode = 4, // Compiled code.
kClosure = 5, // Function closure.
kRegExp = 6, // RegExp.
kHeapNumber = 7, // Number stored in the heap.
kNative = 8, // Native object (not from V8 heap).
kSynthetic = 9, // Synthetic object, usualy used for grouping
// snapshot items together.
kConsString = 10, // Concatenated string. A pair of pointers to strings.
kSlicedString = 11, // Sliced string. A fragment of another string.
kSymbol = 12 // A Symbol (ES6).
};
/** Returns node type (see HeapGraphNode::Type). */
Type GetType() const;
/**
* Returns node name. Depending on node's type this can be the name
* of the constructor (for objects), the name of the function (for
* closures), string value, or an empty string (for compiled code).
*/
Local<String> GetName() const;
/**
* Returns node id. For the same heap object, the id remains the same
* across all snapshots.
*/
SnapshotObjectId GetId() const;
/** Returns node's own size, in bytes. */
size_t GetShallowSize() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child by index. */
const HeapGraphEdge* GetChild(int index) const;
};
/**
* An interface for exporting data from V8, using "push" model.
*/
class V8_EXPORT OutputStream { // NOLINT
public:
enum WriteResult {
kContinue = 0,
kAbort = 1
};
virtual ~OutputStream() {}
/** Notify about the end of stream. */
virtual void EndOfStream() = 0;
/** Get preferred output chunk size. Called only once. */
virtual int GetChunkSize() { return 1024; }
/**
* Writes the next chunk of snapshot data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
/**
* Writes the next chunk of heap stats data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
return kAbort;
}
};
/**
* HeapSnapshots record the state of the JS heap at some moment.
*/
class V8_EXPORT HeapSnapshot {
public:
enum SerializationFormat {
kJSON = 0 // See format description near 'Serialize' method.
};
/** Returns the root node of the heap graph. */
const HeapGraphNode* GetRoot() const;
/** Returns a node by its id. */
const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
/** Returns total nodes count in the snapshot. */
int GetNodesCount() const;
/** Returns a node by index. */
const HeapGraphNode* GetNode(int index) const;
/** Returns a max seen JS object Id. */
SnapshotObjectId GetMaxSnapshotJSObjectId() const;
/**
* Deletes the snapshot and removes it from HeapProfiler's list.
* All pointers to nodes, edges and paths previously returned become
* invalid.
*/
void Delete();
/**
* Prepare a serialized representation of the snapshot. The result
* is written into the stream provided in chunks of specified size.
* The total length of the serialized snapshot is unknown in
* advance, it can be roughly equal to JS heap size (that means,
* it can be really big - tens of megabytes).
*
* For the JSON format, heap contents are represented as an object
* with the following structure:
*
* {
* snapshot: {
* title: "...",
* uid: nnn,
* meta: { meta-info },
* node_count: nnn,
* edge_count: nnn
* },
* nodes: [nodes array],
* edges: [edges array],
* strings: [strings array]
* }
*
* Nodes reference strings, other nodes, and edges by their indexes
* in corresponding arrays.
*/
void Serialize(OutputStream* stream,
SerializationFormat format = kJSON) const;
};
/**
* An interface for reporting progress and controlling long-running
* activities.
*/
class V8_EXPORT ActivityControl { // NOLINT
public:
enum ControlOption {
kContinue = 0,
kAbort = 1
};
virtual ~ActivityControl() {}
/**
* Notify about current progress. The activity can be stopped by
* returning kAbort as the callback result.
*/
virtual ControlOption ReportProgressValue(int done, int total) = 0;
};
/**
* AllocationProfile is a sampled profile of allocations done by the program.
* This is structured as a call-graph.
*/
class V8_EXPORT AllocationProfile {
public:
struct Allocation {
/**
* Size of the sampled allocation object.
*/
size_t size;
/**
* The number of objects of such size that were sampled.
*/
unsigned int count;
};
/**
* Represents a node in the call-graph.
*/
struct Node {
/**
* Name of the function. May be empty for anonymous functions or if the
* script corresponding to this function has been unloaded.
*/
Local<String> name;
/**
* Name of the script containing the function. May be empty if the script
* name is not available, or if the script has been unloaded.
*/
Local<String> script_name;
/**
* id of the script where the function is located. May be equal to
* v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.
*/
int script_id;
/**
* Start position of the function in the script.
*/
int start_position;
/**
* 1-indexed line number where the function starts. May be
* kNoLineNumberInfo if no line number information is available.
*/
int line_number;
/**
* 1-indexed column number where the function starts. May be
* kNoColumnNumberInfo if no line number information is available.
*/
int column_number;
/**
* List of callees called from this node for which we have sampled
* allocations. The lifetime of the children is scoped to the containing
* AllocationProfile.
*/
std::vector<Node*> children;
/**
* List of self allocations done by this node in the call-graph.
*/
std::vector<Allocation> allocations;
};
/**
* 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
* containing AllocationProfile.
*/
virtual Node* GetRootNode() = 0;
virtual ~AllocationProfile() {}
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* Interface for controlling heap profiling. Instance of the
* profiler can be retrieved using v8::Isolate::GetHeapProfiler.
*/
class V8_EXPORT HeapProfiler {
public:
enum SamplingFlags {
kSamplingNoFlags = 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.
*/
typedef RetainerInfos (*GetRetainerInfosCallback)(v8::Isolate* isolate);
/**
* 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. */
int GetSnapshotCount();
/** Returns a snapshot by index. */
const HeapSnapshot* GetHeapSnapshot(int index);
/**
* Returns SnapshotObjectId for a heap object referenced by |value| if
* it has been seen by the heap profiler, kUnknownObjectId otherwise.
*/
SnapshotObjectId GetObjectId(Local<Value> value);
/**
* Returns heap object with given SnapshotObjectId if the object is alive,
* otherwise empty handle is returned.
*/
Local<Value> FindObjectById(SnapshotObjectId id);
/**
* Clears internal map from SnapshotObjectId to heap object. The new objects
* will not be added into it unless a heap snapshot is taken or heap object
* tracking is kicked off.
*/
void ClearObjectIds();
/**
* A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
* it in case heap profiler cannot find id for the object passed as
* parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
*/
static const SnapshotObjectId kUnknownObjectId = 0;
/**
* Callback interface for retrieving user friendly names of global objects.
*/
class ObjectNameResolver {
public:
/**
* Returns name to be used in the heap snapshot for given node. Returned
* string must stay alive until snapshot collection is completed.
*/
virtual const char* GetName(Local<Object> object) = 0;
protected:
virtual ~ObjectNameResolver() {}
};
/**
* Takes a heap snapshot and returns it.
*/
const HeapSnapshot* TakeHeapSnapshot(
ActivityControl* control = NULL,
ObjectNameResolver* global_object_name_resolver = NULL);
/**
* Starts tracking of heap objects population statistics. After calling
* this method, all heap objects relocations done by the garbage collector
* are being registered.
*
* |track_allocations| parameter controls whether stack trace of each
* allocation in the heap will be recorded and reported as part of
* HeapSnapshot.
*/
void StartTrackingHeapObjects(bool track_allocations = false);
/**
* Adds a new time interval entry to the aggregated statistics array. The
* time interval entry contains information on the current heap objects
* population size. The method also updates aggregated statistics and
* reports updates for all previous time intervals via the OutputStream
* object. Updates on each time interval are provided as a stream of the
* HeapStatsUpdate structure instances.
* If |timestamp_us| is supplied, timestamp of the new entry will be written
* into it. The return value of the function is the last seen heap object Id.
*
* StartTrackingHeapObjects must be called before the first call to this
* method.
*/
SnapshotObjectId GetHeapStats(OutputStream* stream,
int64_t* timestamp_us = NULL);
/**
* Stops tracking of heap objects population statistics, cleans up all
* collected data. StartHeapObjectsTracking must be called again prior to
* calling GetHeapStats next time.
*/
void StopTrackingHeapObjects();
/**
* Starts gathering a sampling heap profile. A sampling heap profile is
* similar to tcmalloc's heap profiler and Go's mprof. It samples object
* allocations and builds an online 'sampling' heap profile. At any point in
* time, this profile is expected to be a representative sample of objects
* currently live in the system. Each sampled allocation includes the stack
* trace at the time of allocation, which makes this really useful for memory
* leak detection.
*
* This mechanism is intended to be cheap enough that it can be used in
* production with minimal performance overhead.
*
* Allocations are sampled using a randomized Poisson process. On average, one
* allocation will be sampled every |sample_interval| bytes allocated. The
* |stack_depth| parameter controls the maximum number of stack frames to be
* captured on each allocation.
*
* NOTE: This is a proof-of-concept at this point. Right now we only sample
* newspace allocations. Support for paged space allocation (e.g. pre-tenured
* objects, large objects, code objects, etc.) and native allocations
* doesn't exist yet, but is anticipated in the future.
*
* Objects allocated before the sampling is started will not be included in
* the profile.
*
* Returns false if a sampling heap profiler is already running.
*/
bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
int stack_depth = 16,
SamplingFlags flags = kSamplingNoFlags);
/**
* Stops the sampling heap profile and discards the current profile.
*/
void StopSamplingHeapProfiler();
/**
* Returns the sampled profile of allocations allocated (and still live) since
* StartSamplingHeapProfiler was called. The ownership of the pointer is
* transfered to the caller. Returns nullptr if sampling heap profiler is not
* active.
*/
AllocationProfile* GetAllocationProfile();
/**
* Deletes all snapshots taken. All previously returned pointers to
* snapshots and their contents become invalid after this call.
*/
void DeleteAllHeapSnapshots();
/** Binds a callback to embedder's class ID. */
void SetWrapperClassInfoProvider(
uint16_t class_id,
WrapperInfoCallback callback);
void SetGetRetainerInfosCallback(GetRetainerInfosCallback callback);
/**
* Default value of persistent handle class ID. Must not be used to
* define a class. Can be used to reset a class of a persistent
* handle.
*/
static const uint16_t kPersistentHandleNoClassId = 0;
/** Returns memory used for profiler internal data and snapshots. */
size_t GetProfilerMemorySize();
private:
HeapProfiler();
~HeapProfiler();
HeapProfiler(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.
* See HeapProfiler::GetHeapStats.
*/
struct HeapStatsUpdate {
HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
: index(index), count(count), size(size) { }
uint32_t index; // Index of the time interval that was changed.
uint32_t count; // New value of count field for the interval with this index.
uint32_t size; // New value of size field for the interval with this index.
};
} // namespace v8
#endif // V8_V8_PROFILER_H_

View File

@ -0,0 +1,48 @@
// Copyright 2010 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_TEST_H_
#define V8_V8_TEST_H_
#include "v8.h" // NOLINT(build/include)
/**
* Testing support for the V8 JavaScript engine.
*/
namespace v8 {
class V8_EXPORT Testing {
public:
enum StressType {
kStressTypeOpt,
kStressTypeDeopt
};
/**
* Set the type of stressing to do. The default if not set is kStressTypeOpt.
*/
static void SetStressRunType(StressType type);
/**
* Get the number of runs of a given test that is required to get the full
* stress coverage.
*/
static int GetStressRuns();
/**
* Indicate the number of the run which is about to start. The value of run
* should be between 0 and one less than the result from GetStressRuns()
*/
static void PrepareStressRun(int run);
/**
* Force deoptimization of all functions.
*/
static void DeoptimizeAll(Isolate* isolate);
};
} // namespace v8
#endif // V8_V8_TEST_H_

View File

@ -0,0 +1,655 @@
// Copyright 2014 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_UTIL_H_
#define V8_UTIL_H_
#include "v8.h" // NOLINT(build/include)
#include <assert.h>
#include <map>
#include <vector>
/**
* Support for Persistent containers.
*
* C++11 embedders can use STL containers with Global values,
* but pre-C++11 does not support the required move semantic and hence
* may want these container classes.
*/
namespace v8 {
typedef uintptr_t PersistentContainerValue;
static const uintptr_t kPersistentContainerNotFound = 0;
enum PersistentContainerCallbackType {
kNotWeak,
// These correspond to v8::WeakCallbackType
kWeakWithParameter,
kWeakWithInternalFields,
kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
};
/**
* A default trait implemenation for PersistentValueMap which uses std::map
* as a backing map.
*
* Users will have to implement their own weak callbacks & dispose traits.
*/
template<typename K, typename V>
class StdMapTraits {
public:
// STL map & related:
typedef std::map<K, PersistentContainerValue> Impl;
typedef typename Impl::iterator Iterator;
static bool Empty(Impl* impl) { return impl->empty(); }
static size_t Size(Impl* impl) { return impl->size(); }
static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
static Iterator Begin(Impl* impl) { return impl->begin(); }
static Iterator End(Impl* impl) { return impl->end(); }
static K Key(Iterator it) { return it->first; }
static PersistentContainerValue Value(Iterator it) { return it->second; }
static PersistentContainerValue Set(Impl* impl, K key,
PersistentContainerValue value) {
std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
PersistentContainerValue old_value = kPersistentContainerNotFound;
if (!res.second) {
old_value = res.first->second;
res.first->second = value;
}
return old_value;
}
static PersistentContainerValue Get(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
return it->second;
}
static PersistentContainerValue Remove(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
PersistentContainerValue value = it->second;
impl->erase(it);
return value;
}
};
/**
* A default trait implementation for PersistentValueMap, which inherits
* a std:map backing map from StdMapTraits and holds non-weak persistent
* objects and has no special Dispose handling.
*
* You should not derive from this class, since MapType depends on the
* surrounding class, and hence a subclass cannot simply inherit the methods.
*/
template<typename K, typename V>
class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(
MapType* map, const K& key, Local<V> value) {
return NULL;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return NULL;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) { }
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
};
template <typename K, typename V>
class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
private:
template <typename T>
struct RemovePointer;
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
Local<V> value) {
return nullptr;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return nullptr;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) {}
static void OnWeakCallback(
const WeakCallbackInfo<WeakCallbackDataType>& data) {}
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
// This is a second pass callback, so SetSecondPassCallback cannot be called.
static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {}
private:
template <typename T>
struct RemovePointer<T*> {
typedef T Type;
};
};
/**
* A map wrapper that allows using Global as a mapped value.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* The map relies on a backing map, whose type and accessors are described
* by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template <typename K, typename V, typename Traits>
class PersistentValueMapBase {
public:
Isolate* GetIsolate() { return isolate_; }
/**
* Return size of the map.
*/
size_t Size() { return Traits::Size(&impl_); }
/**
* Return whether the map holds weak persistents.
*/
bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
/**
* Get value stored in map.
*/
Local<V> Get(const K& key) {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
}
/**
* Check whether a value is contained in the map.
*/
bool Contains(const K& key) {
return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
}
/**
* Get value stored in map and set it in returnValue.
* Return true if a value was found.
*/
bool SetReturnValue(const K& key,
ReturnValue<Value> returnValue) {
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
* key.
*/
void RegisterExternallyReferencedObject(K& key) {
assert(Contains(key));
V8::RegisterExternallyReferencedObject(
reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Isolate*>(GetIsolate()));
}
/**
* Return value for key and remove it from the map.
*/
Global<V> Remove(const K& key) {
return Release(Traits::Remove(&impl_, key)).Pass();
}
/**
* Traverses the map repeatedly,
* in case side effects of disposal cause insertions.
**/
void Clear() {
typedef typename Traits::Iterator It;
HandleScope handle_scope(isolate_);
// TODO(dcarney): figure out if this swap and loop is necessary.
while (!Traits::Empty(&impl_)) {
typename Traits::Impl impl;
Traits::Swap(impl_, impl);
for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
Traits::Key(i));
}
}
}
/**
* Helper class for GetReference/SetWithReference. Do not use outside
* that context.
*/
class PersistentValueReference {
public:
PersistentValueReference() : value_(kPersistentContainerNotFound) { }
PersistentValueReference(const PersistentValueReference& other)
: value_(other.value_) { }
Local<V> NewLocal(Isolate* isolate) const {
return Local<V>::New(isolate, FromVal(value_));
}
bool IsEmpty() const {
return value_ == kPersistentContainerNotFound;
}
template<typename T>
bool SetReturnValue(ReturnValue<T> returnValue) {
return SetReturnValueFromVal(&returnValue, value_);
}
void Reset() {
value_ = kPersistentContainerNotFound;
}
void operator=(const PersistentValueReference& other) {
value_ = other.value_;
}
private:
friend class PersistentValueMapBase;
friend class PersistentValueMap<K, V, Traits>;
friend class GlobalValueMap<K, V, Traits>;
explicit PersistentValueReference(PersistentContainerValue value)
: value_(value) { }
void operator=(PersistentContainerValue value) {
value_ = value;
}
PersistentContainerValue value_;
};
/**
* Get a reference to a map value. This enables fast, repeated access
* to a value stored in the map while the map remains unchanged.
*
* Careful: This is potentially unsafe, so please use with care.
* The value will become invalid if the value for this key changes
* in the underlying map, as a result of Set or Remove for the same
* key; as a result of the weak callback for the same key; or as a
* result of calling Clear() or destruction of the map.
*/
PersistentValueReference GetReference(const K& key) {
return PersistentValueReference(Traits::Get(&impl_, key));
}
protected:
explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
~PersistentValueMapBase() { Clear(); }
Isolate* isolate() { return isolate_; }
typename Traits::Impl* impl() { return &impl_; }
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static PersistentContainerValue Leak(Global<V>* persistent) {
return reinterpret_cast<PersistentContainerValue>(persistent->val_);
}
/**
* Return a container value as Global and make sure the weak
* callback is properly disposed of. All remove functionality should go
* through this.
*/
static Global<V> Release(PersistentContainerValue v) {
Global<V> p;
p.val_ = FromVal(v);
if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
Traits::DisposeCallbackData(
p.template ClearWeak<typename Traits::WeakCallbackDataType>());
}
return p.Pass();
}
void RemoveWeak(const K& key) {
Global<V> p;
p.val_ = FromVal(Traits::Remove(&impl_, key));
p.Reset();
}
private:
PersistentValueMapBase(PersistentValueMapBase&);
void operator=(PersistentValueMapBase&);
static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
PersistentContainerValue value) {
bool hasValue = value != kPersistentContainerNotFound;
if (hasValue) {
returnValue->SetInternal(
*reinterpret_cast<internal::Object**>(FromVal(value)));
}
return hasValue;
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
template <typename K, typename V, typename Traits>
class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit PersistentValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), WeakCallback);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void WeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
PersistentValueMap<K, V, Traits>* persistentValueMap =
Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
Traits::Dispose(data.GetIsolate(),
persistentValueMap->Remove(key).Pass(), key);
Traits::DisposeCallbackData(data.GetParameter());
}
}
};
template <typename K, typename V, typename Traits>
class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit GlobalValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
WeakCallbackType callback_type =
Traits::kCallbackType == kWeakWithInternalFields
? WeakCallbackType::kInternalFields
: WeakCallbackType::kParameter;
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
callback_type);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void OnWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
auto map = Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
map->RemoveWeak(key);
Traits::OnWeakCallback(data);
data.SetSecondPassCallback(SecondWeakCallback);
}
}
static void SecondWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
Traits::DisposeWeak(data);
}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Persistents are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template<typename K, typename V,
typename Traits = DefaultPersistentValueMapTraits<K, V> >
class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
public:
explicit StdPersistentValueMap(Isolate* isolate)
: PersistentValueMap<K, V, Traits>(isolate) {}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Globals are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template <typename K, typename V,
typename Traits = DefaultGlobalMapTraits<K, V> >
class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
public:
explicit StdGlobalValueMap(Isolate* isolate)
: GlobalValueMap<K, V, Traits>(isolate) {}
};
class DefaultPersistentValueVectorTraits {
public:
typedef std::vector<PersistentContainerValue> Impl;
static void Append(Impl* impl, PersistentContainerValue value) {
impl->push_back(value);
}
static bool IsEmpty(const Impl* impl) {
return impl->empty();
}
static size_t Size(const Impl* impl) {
return impl->size();
}
static PersistentContainerValue Get(const Impl* impl, size_t i) {
return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
}
static void ReserveCapacity(Impl* impl, size_t capacity) {
impl->reserve(capacity);
}
static void Clear(Impl* impl) {
impl->clear();
}
};
/**
* A vector wrapper that safely stores Global values.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* This class relies on a backing vector implementation, whose type and methods
* are described by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
class PersistentValueVector {
public:
explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
~PersistentValueVector() {
Clear();
}
/**
* Append a value to the vector.
*/
void Append(Local<V> value) {
Global<V> persistent(isolate_, value);
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Append a persistent's value to the vector.
*/
void Append(Global<V> persistent) {
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Are there any values in the vector?
*/
bool IsEmpty() const {
return Traits::IsEmpty(&impl_);
}
/**
* How many elements are in the vector?
*/
size_t Size() const {
return Traits::Size(&impl_);
}
/**
* Retrieve the i-th value in the vector.
*/
Local<V> Get(size_t index) const {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
}
/**
* Remove all elements from the vector.
*/
void Clear() {
size_t length = Traits::Size(&impl_);
for (size_t i = 0; i < length; i++) {
Global<V> p;
p.val_ = FromVal(Traits::Get(&impl_, i));
}
Traits::Clear(&impl_);
}
/**
* Reserve capacity in the vector.
* (Efficiency gains depend on the backing implementation.)
*/
void ReserveCapacity(size_t capacity) {
Traits::ReserveCapacity(&impl_, capacity);
}
private:
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
} // namespace v8
#endif // V8_UTIL_H

View File

@ -0,0 +1,24 @@
// Copyright 2017 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.
/**
* Compile-time constants.
*
* This header provides access to information about the value serializer at
* compile time, without declaring or defining any symbols that require linking
* to V8.
*/
#ifndef INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#define INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#include <stdint.h>
namespace v8 {
constexpr uint32_t CurrentValueSerializerFormatVersion() { return 13; }
} // namespace v8
#endif // INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_

View File

@ -0,0 +1,33 @@
// Copyright 2017 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_VERSION_STRING_H_
#define V8_VERSION_STRING_H_
#include "v8-version.h" // NOLINT(build/include)
// This is here rather than v8-version.h to keep that file simple and
// machine-processable.
#if V8_IS_CANDIDATE_VERSION
#define V8_CANDIDATE_STRING " (candidate)"
#else
#define V8_CANDIDATE_STRING ""
#endif
#define V8_SX(x) #x
#define V8_S(x) V8_SX(x)
#if V8_PATCH_LEVEL > 0
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \
V8_PATCH_LEVEL) V8_CANDIDATE_STRING
#else
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) V8_CANDIDATE_STRING
#endif
#endif // V8_VERSION_STRING_H_

View File

@ -0,0 +1,20 @@
// Copyright 2015 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_INCLUDE_VERSION_H_ // V8_VERSION_H_ conflicts with src/version.h
#define V8_INCLUDE_VERSION_H_
// These macros define the version number for the current version.
// 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.
#define V8_MAJOR_VERSION 6
#define V8_MINOR_VERSION 0
#define V8_BUILD_NUMBER 286
#define V8_PATCH_LEVEL 52
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define V8_IS_CANDIDATE_VERSION 0
#endif // V8_INCLUDE_VERSION_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,428 @@
// Copyright 2013 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 V8CONFIG_H_
#define V8CONFIG_H_
// clang-format off
// Platform headers for feature detection below.
#if defined(__ANDROID__)
# include <sys/cdefs.h>
#elif defined(__APPLE__)
# include <TargetConditionals.h>
#elif defined(__linux__)
# include <features.h>
#endif
// This macro allows to test for the version of the GNU C library (or
// a compatible C library that masquerades as glibc). It evaluates to
// 0 if libc is not GNU libc or compatible.
// Use like:
// #if V8_GLIBC_PREREQ(2, 3)
// ...
// #endif
#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
# define V8_GLIBC_PREREQ(major, minor) \
((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor)))
#else
# define V8_GLIBC_PREREQ(major, minor) 0
#endif
// This macro allows to test for the version of the GNU C++ compiler.
// Note that this also applies to compilers that masquerade as GCC,
// for example clang and the Intel C++ compiler for Linux.
// Use like:
// #if V8_GNUC_PREREQ(4, 3, 1)
// ...
// #endif
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#else
# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
#endif
// -----------------------------------------------------------------------------
// Operating system detection
//
// V8_OS_ANDROID - Android
// V8_OS_BSD - BSDish (Mac OS X, Net/Free/Open/DragonFlyBSD)
// V8_OS_CYGWIN - Cygwin
// V8_OS_DRAGONFLYBSD - DragonFlyBSD
// V8_OS_FREEBSD - FreeBSD
// V8_OS_LINUX - Linux
// V8_OS_MACOSX - Mac OS X
// V8_OS_NETBSD - NetBSD
// V8_OS_OPENBSD - OpenBSD
// V8_OS_POSIX - POSIX compatible (mostly everything except Windows)
// V8_OS_QNX - QNX Neutrino
// V8_OS_SOLARIS - Sun Solaris and OpenSolaris
// V8_OS_AIX - AIX
// V8_OS_WIN - Microsoft Windows
#if defined(__ANDROID__)
# define V8_OS_ANDROID 1
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__APPLE__)
# define V8_OS_BSD 1
# define V8_OS_MACOSX 1
# define V8_OS_POSIX 1
#elif defined(__CYGWIN__)
# define V8_OS_CYGWIN 1
# define V8_OS_POSIX 1
#elif defined(__linux__)
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__sun)
# define V8_OS_POSIX 1
# define V8_OS_SOLARIS 1
#elif defined(_AIX)
#define V8_OS_POSIX 1
#define V8_OS_AIX 1
#elif defined(__FreeBSD__)
# define V8_OS_BSD 1
# define V8_OS_FREEBSD 1
# define V8_OS_POSIX 1
#elif defined(__DragonFly__)
# define V8_OS_BSD 1
# define V8_OS_DRAGONFLYBSD 1
# define V8_OS_POSIX 1
#elif defined(__NetBSD__)
# define V8_OS_BSD 1
# define V8_OS_NETBSD 1
# define V8_OS_POSIX 1
#elif defined(__OpenBSD__)
# define V8_OS_BSD 1
# define V8_OS_OPENBSD 1
# define V8_OS_POSIX 1
#elif defined(__QNXNTO__)
# define V8_OS_POSIX 1
# define V8_OS_QNX 1
#elif defined(_WIN32)
# define V8_OS_WIN 1
#endif
// -----------------------------------------------------------------------------
// C library detection
//
// V8_LIBC_MSVCRT - MSVC libc
// V8_LIBC_BIONIC - Bionic libc
// V8_LIBC_BSD - BSD libc derivate
// V8_LIBC_GLIBC - GNU C library
// V8_LIBC_UCLIBC - uClibc
//
// Note that testing for libc must be done using #if not #ifdef. For example,
// to test for the GNU C library, use:
// #if V8_LIBC_GLIBC
// ...
// #endif
#if defined (_MSC_VER)
# define V8_LIBC_MSVCRT 1
#elif defined(__BIONIC__)
# define V8_LIBC_BIONIC 1
# define V8_LIBC_BSD 1
#elif defined(__UCLIBC__)
// Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC.
# define V8_LIBC_UCLIBC 1
#elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
# define V8_LIBC_GLIBC 1
#else
# define V8_LIBC_BSD V8_OS_BSD
#endif
// -----------------------------------------------------------------------------
// Compiler detection
//
// V8_CC_GNU - GCC, or clang in gcc mode
// V8_CC_INTEL - Intel C++
// V8_CC_MINGW - Minimalist GNU for Windows
// V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
// V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
// V8_CC_MSVC - Microsoft Visual C/C++, or clang in cl.exe mode
//
// C++11 feature detection
//
// V8_HAS_CXX11_ALIGNAS - alignas specifier supported
// V8_HAS_CXX11_ALIGNOF - alignof(type) operator supported
//
// 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))
// supported
// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) 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_VISIBILITY - __attribute__((visibility)) supported
// V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
// supported
// V8_HAS_BUILTIN_CLZ - __builtin_clz() supported
// V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported
// V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported
// V8_HAS_BUILTIN_FRAME_ADDRESS - __builtin_frame_address() supported
// V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported
// V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported
// V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_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_NOINLINE - __declspec(noinline) supported
// V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported
// V8_HAS_DECLSPEC_NORETURN - __declspec(noreturn) supported
// V8_HAS___FORCEINLINE - __forceinline supported
//
// Note that testing for compilers and/or features must be done using #if
// not #ifdef. For example, to test for Intel C++ Compiler, use:
// #if V8_CC_INTEL
// ...
// #endif
#if defined(__clang__)
#if defined(__GNUC__) // Clang in gcc mode.
# define V8_CC_GNU 1
#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_DEPRECATED (__has_attribute(deprecated))
# 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_VISIBILITY (__has_attribute(visibility))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(__has_attribute(warn_unused_result))
# define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
# define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
# define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address))
# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
# define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_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_CXX11_ALIGNAS (__has_feature(cxx_alignas))
#elif defined(__GNUC__)
# define V8_CC_GNU 1
# if defined(__INTEL_COMPILER) // Intel C++ also masquerades as GCC 3.2.0
# define V8_CC_INTEL 1
# endif
# if defined(__MINGW32__)
# define V8_CC_MINGW32 1
# endif
# if defined(__MINGW64__)
# define V8_CC_MINGW64 1
# endif
# 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.
// Works around "sorry, unimplemented: inlining failed" build errors with
// older compilers.
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 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_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_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
# define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_EXPECT (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))
# 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
#if defined(_MSC_VER)
# 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_NOINLINE 1
# define V8_HAS_DECLSPEC_SELECTANY 1
# define V8_HAS_DECLSPEC_NORETURN 1
# define V8_HAS___FORCEINLINE 1
#endif
// -----------------------------------------------------------------------------
// Helper macros
// A macro used to make better inlining. Don't bother for debug builds.
// Use like:
// V8_INLINE int GetZero() { return 0; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
# define V8_INLINE inline __attribute__((always_inline))
#elif !defined(DEBUG) && V8_HAS___FORCEINLINE
# define V8_INLINE __forceinline
#else
# define V8_INLINE inline
#endif
// A macro used to tell the compiler to never inline a particular function.
// Don't bother for debug builds.
// Use like:
// V8_NOINLINE int GetMinusOne() { return -1; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
# define V8_NOINLINE __attribute__((noinline))
#elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
# define V8_NOINLINE __declspec(noinline)
#else
# define V8_NOINLINE /* NOT SUPPORTED */
#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.
#if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATED(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATED(message, declarator) declarator
#endif
// A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated.
#if defined(V8_IMMINENT_DEPRECATION_WARNINGS) && \
V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATE_SOON(message, declarator) declarator
#endif
// A macro to provide the compiler with branch prediction information.
#if V8_HAS_BUILTIN_EXPECT
# define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
# define V8_LIKELY(condition) (__builtin_expect(!!(condition), 1))
#else
# define V8_UNLIKELY(condition) (condition)
# define V8_LIKELY(condition) (condition)
#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.
// Use like:
// int foo() WARN_UNUSED_RESULT;
#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
#endif
// clang-format on
#endif // V8CONFIG_H_

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,29 @@
// Copyright 2016 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_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_
#if defined(_WIN32)
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllexport)
#elif USING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __declspec(dllimport)
#else
#define V8_PLATFORM_EXPORT
#endif // BUILDING_V8_PLATFORM_SHARED
#else // defined(_WIN32)
// Setup for Linux shared library export.
#ifdef BUILDING_V8_PLATFORM_SHARED
#define V8_PLATFORM_EXPORT __attribute__((visibility("default")))
#else
#define V8_PLATFORM_EXPORT
#endif
#endif // defined(_WIN32)
#endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_

View File

@ -0,0 +1,78 @@
// Copyright 2014 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_LIBPLATFORM_LIBPLATFORM_H_
#define V8_LIBPLATFORM_LIBPLATFORM_H_
#include "libplatform/libplatform-export.h"
#include "libplatform/v8-tracing.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace platform {
enum class IdleTaskSupport { kDisabled, kEnabled };
enum class InProcessStackDumping { kDisabled, kEnabled };
enum class MessageLoopBehavior : bool {
kDoNotWait = false,
kWaitForWork = true
};
/**
* Returns a new instance of the default v8::Platform implementation.
*
* The caller will take ownership of the returned pointer. |thread_pool_size|
* is the number of worker threads to allocate for background jobs. If a value
* of zero is passed, a suitable default based on the current number of
* processors online will be chosen.
* If |idle_task_support| is enabled then the platform will accept idle
* tasks (IdleTasksEnabled will return true) and will rely on the embedder
* calling v8::platform::RunIdleTasks to process the idle tasks.
*/
V8_PLATFORM_EXPORT v8::Platform* CreateDefaultPlatform(
int thread_pool_size = 0,
IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
InProcessStackDumping in_process_stack_dumping =
InProcessStackDumping::kEnabled);
/**
* Pumps the message loop for the given isolate.
*
* 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
* through the |behavior| parameter, this call does not block if no task is
* pending. The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT bool PumpMessageLoop(
v8::Platform* platform, v8::Isolate* isolate,
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.
*
* 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
* created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform,
v8::Isolate* isolate,
double idle_time_in_seconds);
/**
* Attempts to set the tracing controller for the given platform.
*
* The |platform| has to be created using |CreateDefaultPlatform|.
*/
V8_PLATFORM_EXPORT void SetTracingController(
v8::Platform* platform,
v8::platform::tracing::TracingController* tracing_controller);
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_LIBPLATFORM_H_

View File

@ -0,0 +1,270 @@
// Copyright 2016 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_LIBPLATFORM_V8_TRACING_H_
#define V8_LIBPLATFORM_V8_TRACING_H_
#include <fstream>
#include <memory>
#include <unordered_set>
#include <vector>
#include "libplatform/libplatform-export.h"
#include "v8-platform.h" // NOLINT(build/include)
namespace v8 {
namespace base {
class Mutex;
} // namespace base
namespace platform {
namespace tracing {
const int kTraceMaxNumArgs = 2;
class V8_PLATFORM_EXPORT TraceObject {
public:
union ArgValue {
bool as_bool;
uint64_t as_uint;
int64_t as_int;
double as_double;
const void* as_pointer;
const char* as_string;
};
TraceObject() {}
~TraceObject();
void Initialize(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateDuration();
void InitializeForTesting(
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** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags, int pid, int tid, int64_t ts, int64_t tts,
uint64_t duration, uint64_t cpu_duration);
int pid() const { return pid_; }
int tid() const { return tid_; }
char phase() const { return phase_; }
const uint8_t* category_enabled_flag() const {
return category_enabled_flag_;
}
const char* name() const { return name_; }
const char* scope() const { return scope_; }
uint64_t id() const { return id_; }
uint64_t bind_id() const { return bind_id_; }
int num_args() const { return num_args_; }
const char** arg_names() { return arg_names_; }
uint8_t* arg_types() { return arg_types_; }
ArgValue* arg_values() { return arg_values_; }
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables() {
return arg_convertables_;
}
unsigned int flags() const { return flags_; }
int64_t ts() { return ts_; }
int64_t tts() { return tts_; }
uint64_t duration() { return duration_; }
uint64_t cpu_duration() { return cpu_duration_; }
private:
int pid_;
int tid_;
char phase_;
const char* name_;
const char* scope_;
const uint8_t* category_enabled_flag_;
uint64_t id_;
uint64_t bind_id_;
int num_args_ = 0;
const char* arg_names_[kTraceMaxNumArgs];
uint8_t arg_types_[kTraceMaxNumArgs];
ArgValue arg_values_[kTraceMaxNumArgs];
std::unique_ptr<v8::ConvertableToTraceFormat>
arg_convertables_[kTraceMaxNumArgs];
char* parameter_copy_storage_ = nullptr;
unsigned int flags_;
int64_t ts_;
int64_t tts_;
uint64_t duration_;
uint64_t cpu_duration_;
// Disallow copy and assign
TraceObject(const TraceObject&) = delete;
void operator=(const TraceObject&) = delete;
};
class V8_PLATFORM_EXPORT TraceWriter {
public:
TraceWriter() {}
virtual ~TraceWriter() {}
virtual void AppendTraceEvent(TraceObject* trace_event) = 0;
virtual void Flush() = 0;
static TraceWriter* CreateJSONTraceWriter(std::ostream& stream);
private:
// Disallow copy and assign
TraceWriter(const TraceWriter&) = delete;
void operator=(const TraceWriter&) = delete;
};
class V8_PLATFORM_EXPORT TraceBufferChunk {
public:
explicit TraceBufferChunk(uint32_t seq);
void Reset(uint32_t new_seq);
bool IsFull() const { return next_free_ == kChunkSize; }
TraceObject* AddTraceEvent(size_t* event_index);
TraceObject* GetEventAt(size_t index) { return &chunk_[index]; }
uint32_t seq() const { return seq_; }
size_t size() const { return next_free_; }
static const size_t kChunkSize = 64;
private:
size_t next_free_ = 0;
TraceObject chunk_[kChunkSize];
uint32_t seq_;
// Disallow copy and assign
TraceBufferChunk(const TraceBufferChunk&) = delete;
void operator=(const TraceBufferChunk&) = delete;
};
class V8_PLATFORM_EXPORT TraceBuffer {
public:
TraceBuffer() {}
virtual ~TraceBuffer() {}
virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0;
virtual TraceObject* GetEventByHandle(uint64_t handle) = 0;
virtual bool Flush() = 0;
static const size_t kRingBufferChunks = 1024;
static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks,
TraceWriter* trace_writer);
private:
// Disallow copy and assign
TraceBuffer(const TraceBuffer&) = delete;
void operator=(const TraceBuffer&) = delete;
};
// Options determines how the trace buffer stores data.
enum TraceRecordMode {
// Record until the trace buffer is full.
RECORD_UNTIL_FULL,
// Record until the user ends the trace. The trace buffer is a fixed size
// and we use it as a ring buffer during recording.
RECORD_CONTINUOUSLY,
// Record until the trace buffer is full, but with a huge buffer size.
RECORD_AS_MUCH_AS_POSSIBLE,
// Echo to console. Events are discarded.
ECHO_TO_CONSOLE,
};
class V8_PLATFORM_EXPORT TraceConfig {
public:
typedef std::vector<std::string> StringList;
static TraceConfig* CreateDefaultTraceConfig();
TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {}
TraceRecordMode GetTraceRecordMode() const { return record_mode_; }
bool IsSystraceEnabled() const { return enable_systrace_; }
bool IsArgumentFilterEnabled() const { return enable_argument_filter_; }
void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; }
void EnableSystrace() { enable_systrace_ = true; }
void EnableArgumentFilter() { enable_argument_filter_ = true; }
void AddIncludedCategory(const char* included_category);
bool IsCategoryGroupEnabled(const char* category_group) const;
private:
TraceRecordMode record_mode_;
bool enable_systrace_ : 1;
bool enable_argument_filter_ : 1;
StringList included_categories_;
// Disallow copy and assign
TraceConfig(const TraceConfig&) = delete;
void operator=(const TraceConfig&) = delete;
};
class V8_PLATFORM_EXPORT TracingController {
public:
enum Mode { DISABLED = 0, RECORDING_MODE };
// The pointer returned from GetCategoryGroupEnabledInternal() 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 {
// Category group enabled for the recording mode.
ENABLED_FOR_RECORDING = 1 << 0,
// Category group enabled by SetEventCallbackEnabled().
ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
// Category group enabled to export events to ETW.
ENABLED_FOR_ETW_EXPORT = 1 << 3
};
TracingController();
~TracingController();
void Initialize(TraceBuffer* trace_buffer);
const uint8_t* GetCategoryGroupEnabled(const char* category_group);
static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag);
uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables,
unsigned int flags);
void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle);
void StartTracing(TraceConfig* trace_config);
void StopTracing();
void AddTraceStateObserver(Platform::TraceStateObserver* observer);
void RemoveTraceStateObserver(Platform::TraceStateObserver* observer);
private:
const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group);
void UpdateCategoryGroupEnabledFlag(size_t category_index);
void UpdateCategoryGroupEnabledFlags();
std::unique_ptr<TraceBuffer> trace_buffer_;
std::unique_ptr<TraceConfig> trace_config_;
std::unique_ptr<base::Mutex> mutex_;
std::unordered_set<Platform::TraceStateObserver*> observers_;
Mode mode_ = DISABLED;
// Disallow copy and assign
TracingController(const TracingController&) = delete;
void operator=(const TracingController&) = delete;
};
} // namespace tracing
} // namespace platform
} // namespace v8
#endif // V8_LIBPLATFORM_V8_TRACING_H_

View File

@ -0,0 +1,255 @@
// 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

@ -0,0 +1,13 @@
// Copyright 2016 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_INSPECTOR_PROTOCOL_H_
#define V8_V8_INSPECTOR_PROTOCOL_H_
#include "inspector/Debugger.h" // NOLINT(build/include)
#include "inspector/Runtime.h" // NOLINT(build/include)
#include "inspector/Schema.h" // NOLINT(build/include)
#include "v8-inspector.h" // NOLINT(build/include)
#endif // V8_V8_INSPECTOR_PROTOCOL_H_

View File

@ -0,0 +1,267 @@
// Copyright 2016 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_INSPECTOR_H_
#define V8_V8_INSPECTOR_H_
#include <stdint.h>
#include <cctype>
#include <memory>
#include "v8.h" // NOLINT(build/include)
namespace v8_inspector {
namespace protocol {
namespace Debugger {
namespace API {
class SearchMatch;
}
}
namespace Runtime {
namespace API {
class RemoteObject;
class StackTrace;
}
}
namespace Schema {
namespace API {
class Domain;
}
}
} // namespace protocol
class V8_EXPORT StringView {
public:
StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {}
StringView(const uint8_t* characters, size_t length)
: m_is8Bit(true), m_length(length), m_characters8(characters) {}
StringView(const uint16_t* characters, size_t length)
: m_is8Bit(false), m_length(length), m_characters16(characters) {}
bool is8Bit() const { return m_is8Bit; }
size_t length() const { return m_length; }
// TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used
// here.
const uint8_t* characters8() const { return m_characters8; }
const uint16_t* characters16() const { return m_characters16; }
private:
bool m_is8Bit;
size_t m_length;
union {
const uint8_t* m_characters8;
const uint16_t* m_characters16;
};
};
class V8_EXPORT StringBuffer {
public:
virtual ~StringBuffer() {}
virtual const StringView& string() = 0;
// This method copies contents.
static std::unique_ptr<StringBuffer> create(const StringView&);
};
class V8_EXPORT V8ContextInfo {
public:
V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId,
const StringView& humanReadableName)
: context(context),
contextGroupId(contextGroupId),
humanReadableName(humanReadableName),
hasMemoryOnConsole(false) {}
v8::Local<v8::Context> context;
// Each v8::Context is a part of a group. The group id must be non-zero.
int contextGroupId;
StringView humanReadableName;
StringView origin;
StringView auxData;
bool hasMemoryOnConsole;
static int executionContextId(v8::Local<v8::Context> context);
private:
// Disallow copying and allocating this one.
enum NotNullTagEnum { NotNullLiteral };
void* operator new(size_t) = delete;
void* operator new(size_t, NotNullTagEnum, void*) = delete;
void* operator new(size_t, void*) = delete;
V8ContextInfo(const V8ContextInfo&) = delete;
V8ContextInfo& operator=(const V8ContextInfo&) = delete;
};
class V8_EXPORT V8StackTrace {
public:
virtual bool isEmpty() const = 0;
virtual StringView topSourceURL() const = 0;
virtual int topLineNumber() const = 0;
virtual int topColumnNumber() const = 0;
virtual StringView topScriptId() const = 0;
virtual StringView topFunctionName() const = 0;
virtual ~V8StackTrace() {}
virtual std::unique_ptr<protocol::Runtime::API::StackTrace>
buildInspectorObject() const = 0;
virtual std::unique_ptr<StringBuffer> toString() const = 0;
// Safe to pass between threads, drops async chain.
virtual std::unique_ptr<V8StackTrace> clone() = 0;
};
class V8_EXPORT V8InspectorSession {
public:
virtual ~V8InspectorSession() {}
// Cross-context inspectable values (DOM nodes in different worlds, etc.).
class V8_EXPORT Inspectable {
public:
virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0;
virtual ~Inspectable() {}
};
virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0;
// Dispatching protocol messages.
static bool canDispatchMethod(const StringView& method);
virtual void dispatchProtocolMessage(const StringView& message) = 0;
virtual std::unique_ptr<StringBuffer> stateJSON() = 0;
virtual std::vector<std::unique_ptr<protocol::Schema::API::Domain>>
supportedDomains() = 0;
// Debugger actions.
virtual void schedulePauseOnNextStatement(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void cancelPauseOnNextStatement() = 0;
virtual void breakProgram(const StringView& breakReason,
const StringView& breakDetails) = 0;
virtual void setSkipAllPauses(bool) = 0;
virtual void resume() = 0;
virtual void stepOver() = 0;
virtual std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>>
searchInTextByLines(const StringView& text, const StringView& query,
bool caseSensitive, bool isRegex) = 0;
// Remote objects.
virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject(
v8::Local<v8::Context>, v8::Local<v8::Value>,
const StringView& groupName) = 0;
virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error,
const StringView& objectId, v8::Local<v8::Value>*,
v8::Local<v8::Context>*,
std::unique_ptr<StringBuffer>* objectGroup) = 0;
virtual void releaseObjectGroup(const StringView&) = 0;
};
class V8_EXPORT V8InspectorClient {
public:
virtual ~V8InspectorClient() {}
virtual void runMessageLoopOnPause(int contextGroupId) {}
virtual void quitMessageLoopOnPause() {}
virtual void runIfWaitingForDebugger(int contextGroupId) {}
virtual void muteMetrics(int contextGroupId) {}
virtual void unmuteMetrics(int contextGroupId) {}
virtual void beginUserGesture() {}
virtual void endUserGesture() {}
virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) {
return nullptr;
}
virtual bool formatAccessorsAsProperties(v8::Local<v8::Value>) {
return false;
}
virtual bool isInspectableHeapObject(v8::Local<v8::Object>) { return true; }
virtual v8::Local<v8::Context> ensureDefaultContextInGroup(
int contextGroupId) {
return v8::Local<v8::Context>();
}
virtual void beginEnsureAllContextsInGroup(int contextGroupId) {}
virtual void endEnsureAllContextsInGroup(int contextGroupId) {}
virtual void installAdditionalCommandLineAPI(v8::Local<v8::Context>,
v8::Local<v8::Object>) {}
virtual void consoleAPIMessage(int contextGroupId,
v8::Isolate::MessageErrorLevel level,
const StringView& message,
const StringView& url, unsigned lineNumber,
unsigned columnNumber, V8StackTrace*) {}
virtual v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*,
v8::Local<v8::Context>) {
return v8::MaybeLocal<v8::Value>();
}
virtual void consoleTime(const StringView& title) {}
virtual void consoleTimeEnd(const StringView& title) {}
virtual void consoleTimeStamp(const StringView& title) {}
virtual void consoleClear(int contextGroupId) {}
virtual double currentTimeMS() { return 0; }
typedef void (*TimerCallback)(void*);
virtual void startRepeatingTimer(double, TimerCallback, void* data) {}
virtual void cancelTimer(void* data) {}
// TODO(dgozman): this was added to support service worker shadow page. We
// should not connect at all.
virtual bool canExecuteScripts(int contextGroupId) { return true; }
};
class V8_EXPORT V8Inspector {
public:
static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*);
virtual ~V8Inspector() {}
// Contexts instrumentation.
virtual void contextCreated(const V8ContextInfo&) = 0;
virtual void contextDestroyed(v8::Local<v8::Context>) = 0;
virtual void resetContextGroup(int contextGroupId) = 0;
// Various instrumentation.
virtual void idleStarted() = 0;
virtual void idleFinished() = 0;
// Async stack traces instrumentation.
virtual void asyncTaskScheduled(const StringView& taskName, void* task,
bool recurring) = 0;
virtual void asyncTaskCanceled(void* task) = 0;
virtual void asyncTaskStarted(void* task) = 0;
virtual void asyncTaskFinished(void* task) = 0;
virtual void allAsyncTasksCanceled() = 0;
// Exceptions instrumentation.
virtual unsigned exceptionThrown(
v8::Local<v8::Context>, const StringView& message,
v8::Local<v8::Value> exception, const StringView& detailedMessage,
const StringView& url, unsigned lineNumber, unsigned columnNumber,
std::unique_ptr<V8StackTrace>, int scriptId) = 0;
virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId,
const StringView& message) = 0;
// Connection.
class V8_EXPORT Channel {
public:
virtual ~Channel() {}
virtual void sendResponse(int callId,
std::unique_ptr<StringBuffer> message) = 0;
virtual void sendNotification(std::unique_ptr<StringBuffer> message) = 0;
virtual void flushProtocolNotifications() = 0;
};
virtual std::unique_ptr<V8InspectorSession> connect(
int contextGroupId, Channel*, const StringView& state) = 0;
// API methods.
virtual std::unique_ptr<V8StackTrace> createStackTrace(
v8::Local<v8::StackTrace>) = 0;
virtual std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) = 0;
};
} // namespace v8_inspector
#endif // V8_V8_INSPECTOR_H_

View File

@ -0,0 +1,227 @@
// Copyright 2013 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_PLATFORM_H_
#define V8_V8_PLATFORM_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
namespace v8 {
class Isolate;
/**
* A Task represents a unit of work.
*/
class Task {
public:
virtual ~Task() = default;
virtual void Run() = 0;
};
/**
* An IdleTask represents a unit of work to be performed in idle time.
* The Run method is invoked with an argument that specifies the deadline in
* seconds returned by MonotonicallyIncreasingTime().
* The idle task is expected to complete by this deadline.
*/
class IdleTask {
public:
virtual ~IdleTask() = default;
virtual void Run(double deadline_in_seconds) = 0;
};
/**
* The interface represents complex arguments to trace events.
*/
class ConvertableToTraceFormat {
public:
virtual ~ConvertableToTraceFormat() = default;
/**
* Append the class info to the provided |out| string. The appended
* data must be a valid JSON object. Strings must be properly quoted, and
* escaped. There is no processing applied to the content after it is
* appended.
*/
virtual void AppendAsTraceFormat(std::string* out) const = 0;
};
/**
* V8 Platform abstraction layer.
*
* The embedder has to provide an implementation of this interface before
* initializing the rest of V8.
*/
class Platform {
public:
/**
* 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.
* The name parameter is a category group for example:
* TRACE_EVENT0("v8,parse", "V8.Parse")
* The pointer returned points to a value with zero or more of the bits
* defined in CategoryGroupEnabledFlags.
**/
virtual const uint8_t* GetCategoryGroupEnabled(const char* name) {
static uint8_t no = 0;
return &no;
}
/**
* Gets the category group name of the given category_enabled_flag pointer.
* 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
* tracing and the category of the particular trace are enabled. It is not
* advisable to call this function on its own; it is really only meant to be
* used by the trace macros. The returned handle can be used by
* UpdateTraceEventDuration to update the duration of COMPLETE events.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values, 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.
*/
virtual uint64_t AddTraceEvent(
char phase, const uint8_t* category_enabled_flag, const char* name,
const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args,
const char** arg_names, const uint8_t* arg_types,
const uint64_t* arg_values,
std::unique_ptr<ConvertableToTraceFormat>* arg_convertables,
unsigned int flags) {
return AddTraceEvent(phase, category_enabled_flag, name, scope, id, bind_id,
num_args, arg_names, arg_types, arg_values, flags);
}
/**
* Sets the duration field of a COMPLETE trace event. It must be called with
* the handle returned from AddTraceEvent().
**/
virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag,
const char* name, uint64_t handle) {}
class TraceStateObserver {
public:
virtual ~TraceStateObserver() = default;
virtual void OnTraceEnabled() = 0;
virtual void OnTraceDisabled() = 0;
};
/** Adds tracing state change observer. */
virtual void AddTraceStateObserver(TraceStateObserver*) {}
/** Removes tracing state change observer. */
virtual void RemoveTraceStateObserver(TraceStateObserver*) {}
typedef void (*StackTracePrinter)();
/**
* Returns a function pointer that print a stack trace of the current stack
* on invocation. Disables printing of the stack trace if nullptr.
*/
virtual StackTracePrinter GetStackTracePrinter() { return nullptr; }
};
} // namespace v8
#endif // V8_V8_PLATFORM_H_

View File

@ -0,0 +1,912 @@
// Copyright 2010 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_PROFILER_H_
#define V8_V8_PROFILER_H_
#include <unordered_set>
#include <vector>
#include "v8.h" // NOLINT(build/include)
/**
* Profiler support for the V8 JavaScript engine.
*/
namespace v8 {
class HeapGraphNode;
struct HeapStatsUpdate;
typedef uint32_t SnapshotObjectId;
struct CpuProfileDeoptFrame {
int script_id;
size_t position;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptFrame>;
#endif
namespace v8 {
struct V8_EXPORT CpuProfileDeoptInfo {
/** A pointer to a static string owned by v8. */
const char* deopt_reason;
std::vector<CpuProfileDeoptFrame> stack;
};
} // namespace v8
#ifdef V8_OS_WIN
template class V8_EXPORT std::vector<v8::CpuProfileDeoptInfo>;
#endif
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.
struct TickSample {
// Internal profiling (with --prof + tools/$OS-tick-processor) wants to
// include the runtime function we're calling. Externally exposed tick
// samples don't care.
enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
TickSample()
: state(OTHER),
pc(nullptr),
external_callback_entry(nullptr),
frames_count(0),
has_external_callback(false),
update_stats(true) {}
/**
* Initialize a tick sample from the isolate.
* \param isolate The isolate.
* \param state Execution state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param update_stats Whether update the sample to the aggregated stats.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
*/
void Init(Isolate* isolate, const v8::RegisterState& state,
RecordCEntryFrame record_c_entry_frame, bool update_stats,
bool use_simulator_reg_state = true);
/**
* Get a call stack sample from the isolate.
* \param isolate The isolate.
* \param state Register state.
* \param record_c_entry_frame Include or skip the runtime function.
* \param frames Caller allocated buffer to store stack frames.
* \param frames_limit Maximum number of frames to capture. The buffer must
* be large enough to hold the number of frames.
* \param sample_info The sample info is filled up by the function
* provides number of actual captured stack frames and
* the current VM state.
* \param use_simulator_reg_state When set to true and V8 is running under a
* simulator, the method will use the simulator
* register state rather than the one provided
* with |state| argument. Otherwise the method
* will use provided register |state| as is.
* \note GetStackSample is thread and signal safe and should only be called
* when the JS thread is paused or interrupted.
* Otherwise the behavior is undefined.
*/
static bool GetStackSample(Isolate* isolate, v8::RegisterState* state,
RecordCEntryFrame record_c_entry_frame,
void** frames, size_t frames_limit,
v8::SampleInfo* sample_info,
bool use_simulator_reg_state = true);
StateTag state; // The state of the VM.
void* pc; // Instruction pointer.
union {
void* tos; // Top stack value (*sp).
void* external_callback_entry;
};
static const unsigned kMaxFramesCountLog2 = 8;
static const unsigned kMaxFramesCount = (1 << kMaxFramesCountLog2) - 1;
void* stack[kMaxFramesCount]; // Call stack.
unsigned frames_count : kMaxFramesCountLog2; // Number of captured frames.
bool has_external_callback : 1;
bool update_stats : 1; // Whether the sample should update aggregated stats.
};
/**
* CpuProfileNode represents a node in a call graph.
*/
class V8_EXPORT CpuProfileNode {
public:
struct LineTick {
/** The 1-based number of the source line where the function originates. */
int line;
/** The count of samples associated with the source line. */
unsigned int hit_count;
};
/** Returns function name (empty string for anonymous functions.) */
Local<String> GetFunctionName() const;
/**
* Returns function name (empty string for anonymous functions.)
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetFunctionNameStr() const;
/** Returns id of the script where function is located. */
int GetScriptId() const;
/** Returns resource name for script from where the function originates. */
Local<String> GetScriptResourceName() const;
/**
* Returns resource name for script from where the function originates.
* The string ownership is *not* passed to the caller. It stays valid until
* profile is deleted. The function is thread safe.
*/
const char* GetScriptResourceNameStr() const;
/**
* Returns the number, 1-based, of the line where the function originates.
* kNoLineNumberInfo if no line number information is available.
*/
int GetLineNumber() const;
/**
* Returns 1-based number of the column where the function originates.
* kNoColumnNumberInfo if no column number information is available.
*/
int GetColumnNumber() const;
/**
* Returns the number of the function's source lines that collect the samples.
*/
unsigned int GetHitLineCount() const;
/** Returns the set of source lines that collect the samples.
* The caller allocates buffer and responsible for releasing it.
* True if all available entries are copied, otherwise false.
* The function copies nothing if buffer is not large enough.
*/
bool GetLineTicks(LineTick* entries, unsigned int length) const;
/** Returns bailout reason for the function
* if the optimization was disabled for it.
*/
const char* GetBailoutReason() const;
/**
* Returns the count of samples where the function was currently executing.
*/
unsigned GetHitCount() const;
/** Returns function entry UID. */
V8_DEPRECATE_SOON(
"Use GetScriptId, GetLineNumber, and GetColumnNumber instead.",
unsigned GetCallUid() const);
/** Returns id of the node. The id is unique within the tree */
unsigned GetNodeId() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child node by index. */
const CpuProfileNode* GetChild(int index) const;
/** Retrieves deopt infos for the node. */
const std::vector<CpuProfileDeoptInfo>& GetDeoptInfos() const;
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* CpuProfile contains a CPU profile in a form of top-down call tree
* (from main() down to functions that do all the work).
*/
class V8_EXPORT CpuProfile {
public:
/** Returns CPU profile title. */
Local<String> GetTitle() const;
/** Returns the root node of the top down call tree. */
const CpuProfileNode* GetTopDownRoot() const;
/**
* Returns number of samples recorded. The samples are not recorded unless
* |record_samples| parameter of CpuProfiler::StartCpuProfiling is true.
*/
int GetSamplesCount() const;
/**
* Returns profile node corresponding to the top frame the sample at
* the given index.
*/
const CpuProfileNode* GetSample(int index) const;
/**
* Returns the timestamp of the sample. The timestamp is the number of
* microseconds since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetSampleTimestamp(int index) const;
/**
* Returns time when the profile recording was started (in microseconds)
* since some unspecified starting point.
*/
int64_t GetStartTime() const;
/**
* Returns time when the profile recording was stopped (in microseconds)
* since some unspecified starting point.
* The point is equal to the starting point used by GetStartTime.
*/
int64_t GetEndTime() const;
/**
* Deletes the profile and removes it from CpuProfiler's list.
* All pointers to nodes previously returned become invalid.
*/
void Delete();
};
/**
* Interface for controlling CPU profiling. Instance of the
* profiler can be created using v8::CpuProfiler::New method.
*/
class V8_EXPORT CpuProfiler {
public:
/**
* Creates a new CPU profiler for the |isolate|. The isolate must be
* initialized. The profiler object must be disposed after use by calling
* |Dispose| method.
*/
static CpuProfiler* New(Isolate* isolate);
/**
* Disposes the CPU profiler object.
*/
void Dispose();
/**
* Changes default CPU profiler sampling interval to the specified number
* of microseconds. Default interval is 1000us. This method must be called
* when there are no profiles being recorded.
*/
void SetSamplingInterval(int us);
/**
* Starts collecting CPU profile. Title may be an empty string. It
* is allowed to have several profiles being collected at
* once. Attempts to start collecting several profiles with the same
* title are silently ignored. While collecting a profile, functions
* from all security contexts are included in it. The token-based
* filtering is only performed when querying for a profile.
*
* |record_samples| parameter controls whether individual samples should
* be recorded in addition to the aggregated tree.
*/
void StartProfiling(Local<String> title, bool record_samples = false);
/**
* Stops collecting CPU profile with a given title and returns it.
* If the title given is empty, finishes the last profile started.
*/
CpuProfile* StopProfiling(Local<String> title);
/**
* Force collection of a sample. Must be called on the VM thread.
* Recording the forced sample does not contribute to the aggregated
* profile statistics.
*/
void CollectSample();
/**
* Tells the profiler whether the embedder is idle.
*/
void SetIdle(bool is_idle);
private:
CpuProfiler();
~CpuProfiler();
CpuProfiler(const CpuProfiler&);
CpuProfiler& operator=(const CpuProfiler&);
};
/**
* HeapSnapshotEdge represents a directed connection between heap
* graph nodes: from retainers to retained nodes.
*/
class V8_EXPORT HeapGraphEdge {
public:
enum Type {
kContextVariable = 0, // A variable from a function context.
kElement = 1, // An element of an array.
kProperty = 2, // A named object property.
kInternal = 3, // A link that can't be accessed from JS,
// thus, its name isn't a real property name
// (e.g. parts of a ConsString).
kHidden = 4, // A link that is needed for proper sizes
// calculation, but may be hidden from user.
kShortcut = 5, // A link that must not be followed during
// sizes calculation.
kWeak = 6 // A weak reference (ignored by the GC).
};
/** Returns edge type (see HeapGraphEdge::Type). */
Type GetType() const;
/**
* Returns edge name. This can be a variable name, an element index, or
* a property name.
*/
Local<Value> GetName() const;
/** Returns origin node. */
const HeapGraphNode* GetFromNode() const;
/** Returns destination node. */
const HeapGraphNode* GetToNode() const;
};
/**
* HeapGraphNode represents a node in a heap graph.
*/
class V8_EXPORT HeapGraphNode {
public:
enum Type {
kHidden = 0, // Hidden node, may be filtered when shown to user.
kArray = 1, // An array of elements.
kString = 2, // A string.
kObject = 3, // A JS object (except for arrays and strings).
kCode = 4, // Compiled code.
kClosure = 5, // Function closure.
kRegExp = 6, // RegExp.
kHeapNumber = 7, // Number stored in the heap.
kNative = 8, // Native object (not from V8 heap).
kSynthetic = 9, // Synthetic object, usualy used for grouping
// snapshot items together.
kConsString = 10, // Concatenated string. A pair of pointers to strings.
kSlicedString = 11, // Sliced string. A fragment of another string.
kSymbol = 12 // A Symbol (ES6).
};
/** Returns node type (see HeapGraphNode::Type). */
Type GetType() const;
/**
* Returns node name. Depending on node's type this can be the name
* of the constructor (for objects), the name of the function (for
* closures), string value, or an empty string (for compiled code).
*/
Local<String> GetName() const;
/**
* Returns node id. For the same heap object, the id remains the same
* across all snapshots.
*/
SnapshotObjectId GetId() const;
/** Returns node's own size, in bytes. */
size_t GetShallowSize() const;
/** Returns child nodes count of the node. */
int GetChildrenCount() const;
/** Retrieves a child by index. */
const HeapGraphEdge* GetChild(int index) const;
};
/**
* An interface for exporting data from V8, using "push" model.
*/
class V8_EXPORT OutputStream { // NOLINT
public:
enum WriteResult {
kContinue = 0,
kAbort = 1
};
virtual ~OutputStream() {}
/** Notify about the end of stream. */
virtual void EndOfStream() = 0;
/** Get preferred output chunk size. Called only once. */
virtual int GetChunkSize() { return 1024; }
/**
* Writes the next chunk of snapshot data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteAsciiChunk(char* data, int size) = 0;
/**
* Writes the next chunk of heap stats data into the stream. Writing
* can be stopped by returning kAbort as function result. EndOfStream
* will not be called in case writing was aborted.
*/
virtual WriteResult WriteHeapStatsChunk(HeapStatsUpdate* data, int count) {
return kAbort;
}
};
/**
* HeapSnapshots record the state of the JS heap at some moment.
*/
class V8_EXPORT HeapSnapshot {
public:
enum SerializationFormat {
kJSON = 0 // See format description near 'Serialize' method.
};
/** Returns the root node of the heap graph. */
const HeapGraphNode* GetRoot() const;
/** Returns a node by its id. */
const HeapGraphNode* GetNodeById(SnapshotObjectId id) const;
/** Returns total nodes count in the snapshot. */
int GetNodesCount() const;
/** Returns a node by index. */
const HeapGraphNode* GetNode(int index) const;
/** Returns a max seen JS object Id. */
SnapshotObjectId GetMaxSnapshotJSObjectId() const;
/**
* Deletes the snapshot and removes it from HeapProfiler's list.
* All pointers to nodes, edges and paths previously returned become
* invalid.
*/
void Delete();
/**
* Prepare a serialized representation of the snapshot. The result
* is written into the stream provided in chunks of specified size.
* The total length of the serialized snapshot is unknown in
* advance, it can be roughly equal to JS heap size (that means,
* it can be really big - tens of megabytes).
*
* For the JSON format, heap contents are represented as an object
* with the following structure:
*
* {
* snapshot: {
* title: "...",
* uid: nnn,
* meta: { meta-info },
* node_count: nnn,
* edge_count: nnn
* },
* nodes: [nodes array],
* edges: [edges array],
* strings: [strings array]
* }
*
* Nodes reference strings, other nodes, and edges by their indexes
* in corresponding arrays.
*/
void Serialize(OutputStream* stream,
SerializationFormat format = kJSON) const;
};
/**
* An interface for reporting progress and controlling long-running
* activities.
*/
class V8_EXPORT ActivityControl { // NOLINT
public:
enum ControlOption {
kContinue = 0,
kAbort = 1
};
virtual ~ActivityControl() {}
/**
* Notify about current progress. The activity can be stopped by
* returning kAbort as the callback result.
*/
virtual ControlOption ReportProgressValue(int done, int total) = 0;
};
/**
* AllocationProfile is a sampled profile of allocations done by the program.
* This is structured as a call-graph.
*/
class V8_EXPORT AllocationProfile {
public:
struct Allocation {
/**
* Size of the sampled allocation object.
*/
size_t size;
/**
* The number of objects of such size that were sampled.
*/
unsigned int count;
};
/**
* Represents a node in the call-graph.
*/
struct Node {
/**
* Name of the function. May be empty for anonymous functions or if the
* script corresponding to this function has been unloaded.
*/
Local<String> name;
/**
* Name of the script containing the function. May be empty if the script
* name is not available, or if the script has been unloaded.
*/
Local<String> script_name;
/**
* id of the script where the function is located. May be equal to
* v8::UnboundScript::kNoScriptId in cases where the script doesn't exist.
*/
int script_id;
/**
* Start position of the function in the script.
*/
int start_position;
/**
* 1-indexed line number where the function starts. May be
* kNoLineNumberInfo if no line number information is available.
*/
int line_number;
/**
* 1-indexed column number where the function starts. May be
* kNoColumnNumberInfo if no line number information is available.
*/
int column_number;
/**
* List of callees called from this node for which we have sampled
* allocations. The lifetime of the children is scoped to the containing
* AllocationProfile.
*/
std::vector<Node*> children;
/**
* List of self allocations done by this node in the call-graph.
*/
std::vector<Allocation> allocations;
};
/**
* 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
* containing AllocationProfile.
*/
virtual Node* GetRootNode() = 0;
virtual ~AllocationProfile() {}
static const int kNoLineNumberInfo = Message::kNoLineNumberInfo;
static const int kNoColumnNumberInfo = Message::kNoColumnInfo;
};
/**
* Interface for controlling heap profiling. Instance of the
* profiler can be retrieved using v8::Isolate::GetHeapProfiler.
*/
class V8_EXPORT HeapProfiler {
public:
enum SamplingFlags {
kSamplingNoFlags = 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.
*/
typedef RetainerInfos (*GetRetainerInfosCallback)(v8::Isolate* isolate);
/**
* 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. */
int GetSnapshotCount();
/** Returns a snapshot by index. */
const HeapSnapshot* GetHeapSnapshot(int index);
/**
* Returns SnapshotObjectId for a heap object referenced by |value| if
* it has been seen by the heap profiler, kUnknownObjectId otherwise.
*/
SnapshotObjectId GetObjectId(Local<Value> value);
/**
* Returns heap object with given SnapshotObjectId if the object is alive,
* otherwise empty handle is returned.
*/
Local<Value> FindObjectById(SnapshotObjectId id);
/**
* Clears internal map from SnapshotObjectId to heap object. The new objects
* will not be added into it unless a heap snapshot is taken or heap object
* tracking is kicked off.
*/
void ClearObjectIds();
/**
* A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return
* it in case heap profiler cannot find id for the object passed as
* parameter. HeapSnapshot::GetNodeById will always return NULL for such id.
*/
static const SnapshotObjectId kUnknownObjectId = 0;
/**
* Callback interface for retrieving user friendly names of global objects.
*/
class ObjectNameResolver {
public:
/**
* Returns name to be used in the heap snapshot for given node. Returned
* string must stay alive until snapshot collection is completed.
*/
virtual const char* GetName(Local<Object> object) = 0;
protected:
virtual ~ObjectNameResolver() {}
};
/**
* Takes a heap snapshot and returns it.
*/
const HeapSnapshot* TakeHeapSnapshot(
ActivityControl* control = NULL,
ObjectNameResolver* global_object_name_resolver = NULL);
/**
* Starts tracking of heap objects population statistics. After calling
* this method, all heap objects relocations done by the garbage collector
* are being registered.
*
* |track_allocations| parameter controls whether stack trace of each
* allocation in the heap will be recorded and reported as part of
* HeapSnapshot.
*/
void StartTrackingHeapObjects(bool track_allocations = false);
/**
* Adds a new time interval entry to the aggregated statistics array. The
* time interval entry contains information on the current heap objects
* population size. The method also updates aggregated statistics and
* reports updates for all previous time intervals via the OutputStream
* object. Updates on each time interval are provided as a stream of the
* HeapStatsUpdate structure instances.
* If |timestamp_us| is supplied, timestamp of the new entry will be written
* into it. The return value of the function is the last seen heap object Id.
*
* StartTrackingHeapObjects must be called before the first call to this
* method.
*/
SnapshotObjectId GetHeapStats(OutputStream* stream,
int64_t* timestamp_us = NULL);
/**
* Stops tracking of heap objects population statistics, cleans up all
* collected data. StartHeapObjectsTracking must be called again prior to
* calling GetHeapStats next time.
*/
void StopTrackingHeapObjects();
/**
* Starts gathering a sampling heap profile. A sampling heap profile is
* similar to tcmalloc's heap profiler and Go's mprof. It samples object
* allocations and builds an online 'sampling' heap profile. At any point in
* time, this profile is expected to be a representative sample of objects
* currently live in the system. Each sampled allocation includes the stack
* trace at the time of allocation, which makes this really useful for memory
* leak detection.
*
* This mechanism is intended to be cheap enough that it can be used in
* production with minimal performance overhead.
*
* Allocations are sampled using a randomized Poisson process. On average, one
* allocation will be sampled every |sample_interval| bytes allocated. The
* |stack_depth| parameter controls the maximum number of stack frames to be
* captured on each allocation.
*
* NOTE: This is a proof-of-concept at this point. Right now we only sample
* newspace allocations. Support for paged space allocation (e.g. pre-tenured
* objects, large objects, code objects, etc.) and native allocations
* doesn't exist yet, but is anticipated in the future.
*
* Objects allocated before the sampling is started will not be included in
* the profile.
*
* Returns false if a sampling heap profiler is already running.
*/
bool StartSamplingHeapProfiler(uint64_t sample_interval = 512 * 1024,
int stack_depth = 16,
SamplingFlags flags = kSamplingNoFlags);
/**
* Stops the sampling heap profile and discards the current profile.
*/
void StopSamplingHeapProfiler();
/**
* Returns the sampled profile of allocations allocated (and still live) since
* StartSamplingHeapProfiler was called. The ownership of the pointer is
* transfered to the caller. Returns nullptr if sampling heap profiler is not
* active.
*/
AllocationProfile* GetAllocationProfile();
/**
* Deletes all snapshots taken. All previously returned pointers to
* snapshots and their contents become invalid after this call.
*/
void DeleteAllHeapSnapshots();
/** Binds a callback to embedder's class ID. */
void SetWrapperClassInfoProvider(
uint16_t class_id,
WrapperInfoCallback callback);
void SetGetRetainerInfosCallback(GetRetainerInfosCallback callback);
/**
* Default value of persistent handle class ID. Must not be used to
* define a class. Can be used to reset a class of a persistent
* handle.
*/
static const uint16_t kPersistentHandleNoClassId = 0;
/** Returns memory used for profiler internal data and snapshots. */
size_t GetProfilerMemorySize();
private:
HeapProfiler();
~HeapProfiler();
HeapProfiler(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.
* See HeapProfiler::GetHeapStats.
*/
struct HeapStatsUpdate {
HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size)
: index(index), count(count), size(size) { }
uint32_t index; // Index of the time interval that was changed.
uint32_t count; // New value of count field for the interval with this index.
uint32_t size; // New value of size field for the interval with this index.
};
} // namespace v8
#endif // V8_V8_PROFILER_H_

View File

@ -0,0 +1,48 @@
// Copyright 2010 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_TEST_H_
#define V8_V8_TEST_H_
#include "v8.h" // NOLINT(build/include)
/**
* Testing support for the V8 JavaScript engine.
*/
namespace v8 {
class V8_EXPORT Testing {
public:
enum StressType {
kStressTypeOpt,
kStressTypeDeopt
};
/**
* Set the type of stressing to do. The default if not set is kStressTypeOpt.
*/
static void SetStressRunType(StressType type);
/**
* Get the number of runs of a given test that is required to get the full
* stress coverage.
*/
static int GetStressRuns();
/**
* Indicate the number of the run which is about to start. The value of run
* should be between 0 and one less than the result from GetStressRuns()
*/
static void PrepareStressRun(int run);
/**
* Force deoptimization of all functions.
*/
static void DeoptimizeAll(Isolate* isolate);
};
} // namespace v8
#endif // V8_V8_TEST_H_

View File

@ -0,0 +1,655 @@
// Copyright 2014 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_UTIL_H_
#define V8_UTIL_H_
#include "v8.h" // NOLINT(build/include)
#include <assert.h>
#include <map>
#include <vector>
/**
* Support for Persistent containers.
*
* C++11 embedders can use STL containers with Global values,
* but pre-C++11 does not support the required move semantic and hence
* may want these container classes.
*/
namespace v8 {
typedef uintptr_t PersistentContainerValue;
static const uintptr_t kPersistentContainerNotFound = 0;
enum PersistentContainerCallbackType {
kNotWeak,
// These correspond to v8::WeakCallbackType
kWeakWithParameter,
kWeakWithInternalFields,
kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
};
/**
* A default trait implemenation for PersistentValueMap which uses std::map
* as a backing map.
*
* Users will have to implement their own weak callbacks & dispose traits.
*/
template<typename K, typename V>
class StdMapTraits {
public:
// STL map & related:
typedef std::map<K, PersistentContainerValue> Impl;
typedef typename Impl::iterator Iterator;
static bool Empty(Impl* impl) { return impl->empty(); }
static size_t Size(Impl* impl) { return impl->size(); }
static void Swap(Impl& a, Impl& b) { std::swap(a, b); } // NOLINT
static Iterator Begin(Impl* impl) { return impl->begin(); }
static Iterator End(Impl* impl) { return impl->end(); }
static K Key(Iterator it) { return it->first; }
static PersistentContainerValue Value(Iterator it) { return it->second; }
static PersistentContainerValue Set(Impl* impl, K key,
PersistentContainerValue value) {
std::pair<Iterator, bool> res = impl->insert(std::make_pair(key, value));
PersistentContainerValue old_value = kPersistentContainerNotFound;
if (!res.second) {
old_value = res.first->second;
res.first->second = value;
}
return old_value;
}
static PersistentContainerValue Get(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
return it->second;
}
static PersistentContainerValue Remove(Impl* impl, K key) {
Iterator it = impl->find(key);
if (it == impl->end()) return kPersistentContainerNotFound;
PersistentContainerValue value = it->second;
impl->erase(it);
return value;
}
};
/**
* A default trait implementation for PersistentValueMap, which inherits
* a std:map backing map from StdMapTraits and holds non-weak persistent
* objects and has no special Dispose handling.
*
* You should not derive from this class, since MapType depends on the
* surrounding class, and hence a subclass cannot simply inherit the methods.
*/
template<typename K, typename V>
class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(
MapType* map, const K& key, Local<V> value) {
return NULL;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return NULL;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) { }
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
};
template <typename K, typename V>
class DefaultGlobalMapTraits : public StdMapTraits<K, V> {
private:
template <typename T>
struct RemovePointer;
public:
// Weak callback & friends:
static const PersistentContainerCallbackType kCallbackType = kNotWeak;
typedef GlobalValueMap<K, V, DefaultGlobalMapTraits<K, V> > MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
Local<V> value) {
return nullptr;
}
static MapType* MapFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return nullptr;
}
static K KeyFromWeakCallbackInfo(
const WeakCallbackInfo<WeakCallbackDataType>& data) {
return K();
}
static void DisposeCallbackData(WeakCallbackDataType* data) {}
static void OnWeakCallback(
const WeakCallbackInfo<WeakCallbackDataType>& data) {}
static void Dispose(Isolate* isolate, Global<V> value, K key) {}
// This is a second pass callback, so SetSecondPassCallback cannot be called.
static void DisposeWeak(const WeakCallbackInfo<WeakCallbackDataType>& data) {}
private:
template <typename T>
struct RemovePointer<T*> {
typedef T Type;
};
};
/**
* A map wrapper that allows using Global as a mapped value.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* The map relies on a backing map, whose type and accessors are described
* by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template <typename K, typename V, typename Traits>
class PersistentValueMapBase {
public:
Isolate* GetIsolate() { return isolate_; }
/**
* Return size of the map.
*/
size_t Size() { return Traits::Size(&impl_); }
/**
* Return whether the map holds weak persistents.
*/
bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
/**
* Get value stored in map.
*/
Local<V> Get(const K& key) {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, key)));
}
/**
* Check whether a value is contained in the map.
*/
bool Contains(const K& key) {
return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
}
/**
* Get value stored in map and set it in returnValue.
* Return true if a value was found.
*/
bool SetReturnValue(const K& key,
ReturnValue<Value> returnValue) {
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
* key.
*/
void RegisterExternallyReferencedObject(K& key) {
assert(Contains(key));
V8::RegisterExternallyReferencedObject(
reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Isolate*>(GetIsolate()));
}
/**
* Return value for key and remove it from the map.
*/
Global<V> Remove(const K& key) {
return Release(Traits::Remove(&impl_, key)).Pass();
}
/**
* Traverses the map repeatedly,
* in case side effects of disposal cause insertions.
**/
void Clear() {
typedef typename Traits::Iterator It;
HandleScope handle_scope(isolate_);
// TODO(dcarney): figure out if this swap and loop is necessary.
while (!Traits::Empty(&impl_)) {
typename Traits::Impl impl;
Traits::Swap(impl_, impl);
for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
Traits::Key(i));
}
}
}
/**
* Helper class for GetReference/SetWithReference. Do not use outside
* that context.
*/
class PersistentValueReference {
public:
PersistentValueReference() : value_(kPersistentContainerNotFound) { }
PersistentValueReference(const PersistentValueReference& other)
: value_(other.value_) { }
Local<V> NewLocal(Isolate* isolate) const {
return Local<V>::New(isolate, FromVal(value_));
}
bool IsEmpty() const {
return value_ == kPersistentContainerNotFound;
}
template<typename T>
bool SetReturnValue(ReturnValue<T> returnValue) {
return SetReturnValueFromVal(&returnValue, value_);
}
void Reset() {
value_ = kPersistentContainerNotFound;
}
void operator=(const PersistentValueReference& other) {
value_ = other.value_;
}
private:
friend class PersistentValueMapBase;
friend class PersistentValueMap<K, V, Traits>;
friend class GlobalValueMap<K, V, Traits>;
explicit PersistentValueReference(PersistentContainerValue value)
: value_(value) { }
void operator=(PersistentContainerValue value) {
value_ = value;
}
PersistentContainerValue value_;
};
/**
* Get a reference to a map value. This enables fast, repeated access
* to a value stored in the map while the map remains unchanged.
*
* Careful: This is potentially unsafe, so please use with care.
* The value will become invalid if the value for this key changes
* in the underlying map, as a result of Set or Remove for the same
* key; as a result of the weak callback for the same key; or as a
* result of calling Clear() or destruction of the map.
*/
PersistentValueReference GetReference(const K& key) {
return PersistentValueReference(Traits::Get(&impl_, key));
}
protected:
explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {}
~PersistentValueMapBase() { Clear(); }
Isolate* isolate() { return isolate_; }
typename Traits::Impl* impl() { return &impl_; }
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static PersistentContainerValue Leak(Global<V>* persistent) {
return reinterpret_cast<PersistentContainerValue>(persistent->val_);
}
/**
* Return a container value as Global and make sure the weak
* callback is properly disposed of. All remove functionality should go
* through this.
*/
static Global<V> Release(PersistentContainerValue v) {
Global<V> p;
p.val_ = FromVal(v);
if (Traits::kCallbackType != kNotWeak && p.IsWeak()) {
Traits::DisposeCallbackData(
p.template ClearWeak<typename Traits::WeakCallbackDataType>());
}
return p.Pass();
}
void RemoveWeak(const K& key) {
Global<V> p;
p.val_ = FromVal(Traits::Remove(&impl_, key));
p.Reset();
}
private:
PersistentValueMapBase(PersistentValueMapBase&);
void operator=(PersistentValueMapBase&);
static bool SetReturnValueFromVal(ReturnValue<Value>* returnValue,
PersistentContainerValue value) {
bool hasValue = value != kPersistentContainerNotFound;
if (hasValue) {
returnValue->SetInternal(
*reinterpret_cast<internal::Object**>(FromVal(value)));
}
return hasValue;
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
template <typename K, typename V, typename Traits>
class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit PersistentValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), WeakCallback);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void WeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
PersistentValueMap<K, V, Traits>* persistentValueMap =
Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
Traits::Dispose(data.GetIsolate(),
persistentValueMap->Remove(key).Pass(), key);
Traits::DisposeCallbackData(data.GetParameter());
}
}
};
template <typename K, typename V, typename Traits>
class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> {
public:
explicit GlobalValueMap(Isolate* isolate)
: PersistentValueMapBase<K, V, Traits>(isolate) {}
typedef
typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference
PersistentValueReference;
/**
* Put value into map. Depending on Traits::kIsWeak, the value will be held
* by the map strongly or weakly.
* Returns old value as Global.
*/
Global<V> Set(const K& key, Local<V> value) {
Global<V> persistent(this->isolate(), value);
return SetUnique(key, &persistent);
}
/**
* Put value into map, like Set(const K&, Local<V>).
*/
Global<V> Set(const K& key, Global<V> value) {
return SetUnique(key, &value);
}
/**
* Put the value into the map, and set the 'weak' callback when demanded
* by the Traits class.
*/
Global<V> SetUnique(const K& key, Global<V>* persistent) {
if (Traits::kCallbackType != kNotWeak) {
WeakCallbackType callback_type =
Traits::kCallbackType == kWeakWithInternalFields
? WeakCallbackType::kInternalFields
: WeakCallbackType::kParameter;
Local<V> value(Local<V>::New(this->isolate(), *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
Traits::WeakCallbackParameter(this, key, value), OnWeakCallback,
callback_type);
}
PersistentContainerValue old_value =
Traits::Set(this->impl(), key, this->ClearAndLeak(persistent));
return this->Release(old_value).Pass();
}
/**
* Put a value into the map and update the reference.
* Restrictions of GetReference apply here as well.
*/
Global<V> Set(const K& key, Global<V> value,
PersistentValueReference* reference) {
*reference = this->Leak(&value);
return SetUnique(key, &value);
}
private:
static void OnWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
if (Traits::kCallbackType != kNotWeak) {
auto map = Traits::MapFromWeakCallbackInfo(data);
K key = Traits::KeyFromWeakCallbackInfo(data);
map->RemoveWeak(key);
Traits::OnWeakCallback(data);
data.SetSecondPassCallback(SecondWeakCallback);
}
}
static void SecondWeakCallback(
const WeakCallbackInfo<typename Traits::WeakCallbackDataType>& data) {
Traits::DisposeWeak(data);
}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Persistents are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template<typename K, typename V,
typename Traits = DefaultPersistentValueMapTraits<K, V> >
class StdPersistentValueMap : public PersistentValueMap<K, V, Traits> {
public:
explicit StdPersistentValueMap(Isolate* isolate)
: PersistentValueMap<K, V, Traits>(isolate) {}
};
/**
* A map that uses Global as value and std::map as the backing
* implementation. Globals are held non-weak.
*
* C++11 embedders don't need this class, as they can use
* Global directly in std containers.
*/
template <typename K, typename V,
typename Traits = DefaultGlobalMapTraits<K, V> >
class StdGlobalValueMap : public GlobalValueMap<K, V, Traits> {
public:
explicit StdGlobalValueMap(Isolate* isolate)
: GlobalValueMap<K, V, Traits>(isolate) {}
};
class DefaultPersistentValueVectorTraits {
public:
typedef std::vector<PersistentContainerValue> Impl;
static void Append(Impl* impl, PersistentContainerValue value) {
impl->push_back(value);
}
static bool IsEmpty(const Impl* impl) {
return impl->empty();
}
static size_t Size(const Impl* impl) {
return impl->size();
}
static PersistentContainerValue Get(const Impl* impl, size_t i) {
return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
}
static void ReserveCapacity(Impl* impl, size_t capacity) {
impl->reserve(capacity);
}
static void Clear(Impl* impl) {
impl->clear();
}
};
/**
* A vector wrapper that safely stores Global values.
* C++11 embedders don't need this class, as they can use Global
* directly in std containers.
*
* This class relies on a backing vector implementation, whose type and methods
* are described by the Traits class. The backing map will handle values of type
* PersistentContainerValue, with all conversion into and out of V8
* handles being transparently handled by this class.
*/
template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
class PersistentValueVector {
public:
explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
~PersistentValueVector() {
Clear();
}
/**
* Append a value to the vector.
*/
void Append(Local<V> value) {
Global<V> persistent(isolate_, value);
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Append a persistent's value to the vector.
*/
void Append(Global<V> persistent) {
Traits::Append(&impl_, ClearAndLeak(&persistent));
}
/**
* Are there any values in the vector?
*/
bool IsEmpty() const {
return Traits::IsEmpty(&impl_);
}
/**
* How many elements are in the vector?
*/
size_t Size() const {
return Traits::Size(&impl_);
}
/**
* Retrieve the i-th value in the vector.
*/
Local<V> Get(size_t index) const {
return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
}
/**
* Remove all elements from the vector.
*/
void Clear() {
size_t length = Traits::Size(&impl_);
for (size_t i = 0; i < length; i++) {
Global<V> p;
p.val_ = FromVal(Traits::Get(&impl_, i));
}
Traits::Clear(&impl_);
}
/**
* Reserve capacity in the vector.
* (Efficiency gains depend on the backing implementation.)
*/
void ReserveCapacity(size_t capacity) {
Traits::ReserveCapacity(&impl_, capacity);
}
private:
static PersistentContainerValue ClearAndLeak(Global<V>* persistent) {
V* v = persistent->val_;
persistent->val_ = 0;
return reinterpret_cast<PersistentContainerValue>(v);
}
static V* FromVal(PersistentContainerValue v) {
return reinterpret_cast<V*>(v);
}
Isolate* isolate_;
typename Traits::Impl impl_;
};
} // namespace v8
#endif // V8_UTIL_H

View File

@ -0,0 +1,24 @@
// Copyright 2017 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.
/**
* Compile-time constants.
*
* This header provides access to information about the value serializer at
* compile time, without declaring or defining any symbols that require linking
* to V8.
*/
#ifndef INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#define INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_
#include <stdint.h>
namespace v8 {
constexpr uint32_t CurrentValueSerializerFormatVersion() { return 13; }
} // namespace v8
#endif // INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_

View File

@ -0,0 +1,33 @@
// Copyright 2017 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_VERSION_STRING_H_
#define V8_VERSION_STRING_H_
#include "v8-version.h" // NOLINT(build/include)
// This is here rather than v8-version.h to keep that file simple and
// machine-processable.
#if V8_IS_CANDIDATE_VERSION
#define V8_CANDIDATE_STRING " (candidate)"
#else
#define V8_CANDIDATE_STRING ""
#endif
#define V8_SX(x) #x
#define V8_S(x) V8_SX(x)
#if V8_PATCH_LEVEL > 0
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \
V8_PATCH_LEVEL) V8_CANDIDATE_STRING
#else
#define V8_VERSION_STRING \
V8_S(V8_MAJOR_VERSION) \
"." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) V8_CANDIDATE_STRING
#endif
#endif // V8_VERSION_STRING_H_

View File

@ -0,0 +1,20 @@
// Copyright 2015 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_INCLUDE_VERSION_H_ // V8_VERSION_H_ conflicts with src/version.h
#define V8_INCLUDE_VERSION_H_
// These macros define the version number for the current version.
// 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.
#define V8_MAJOR_VERSION 6
#define V8_MINOR_VERSION 0
#define V8_BUILD_NUMBER 286
#define V8_PATCH_LEVEL 52
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define V8_IS_CANDIDATE_VERSION 0
#endif // V8_INCLUDE_VERSION_H_

10155
android/x86/include/v8/v8.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,428 @@
// Copyright 2013 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 V8CONFIG_H_
#define V8CONFIG_H_
// clang-format off
// Platform headers for feature detection below.
#if defined(__ANDROID__)
# include <sys/cdefs.h>
#elif defined(__APPLE__)
# include <TargetConditionals.h>
#elif defined(__linux__)
# include <features.h>
#endif
// This macro allows to test for the version of the GNU C library (or
// a compatible C library that masquerades as glibc). It evaluates to
// 0 if libc is not GNU libc or compatible.
// Use like:
// #if V8_GLIBC_PREREQ(2, 3)
// ...
// #endif
#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
# define V8_GLIBC_PREREQ(major, minor) \
((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor)))
#else
# define V8_GLIBC_PREREQ(major, minor) 0
#endif
// This macro allows to test for the version of the GNU C++ compiler.
// Note that this also applies to compilers that masquerade as GCC,
// for example clang and the Intel C++ compiler for Linux.
// Use like:
// #if V8_GNUC_PREREQ(4, 3, 1)
// ...
// #endif
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
#else
# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
#endif
// -----------------------------------------------------------------------------
// Operating system detection
//
// V8_OS_ANDROID - Android
// V8_OS_BSD - BSDish (Mac OS X, Net/Free/Open/DragonFlyBSD)
// V8_OS_CYGWIN - Cygwin
// V8_OS_DRAGONFLYBSD - DragonFlyBSD
// V8_OS_FREEBSD - FreeBSD
// V8_OS_LINUX - Linux
// V8_OS_MACOSX - Mac OS X
// V8_OS_NETBSD - NetBSD
// V8_OS_OPENBSD - OpenBSD
// V8_OS_POSIX - POSIX compatible (mostly everything except Windows)
// V8_OS_QNX - QNX Neutrino
// V8_OS_SOLARIS - Sun Solaris and OpenSolaris
// V8_OS_AIX - AIX
// V8_OS_WIN - Microsoft Windows
#if defined(__ANDROID__)
# define V8_OS_ANDROID 1
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__APPLE__)
# define V8_OS_BSD 1
# define V8_OS_MACOSX 1
# define V8_OS_POSIX 1
#elif defined(__CYGWIN__)
# define V8_OS_CYGWIN 1
# define V8_OS_POSIX 1
#elif defined(__linux__)
# define V8_OS_LINUX 1
# define V8_OS_POSIX 1
#elif defined(__sun)
# define V8_OS_POSIX 1
# define V8_OS_SOLARIS 1
#elif defined(_AIX)
#define V8_OS_POSIX 1
#define V8_OS_AIX 1
#elif defined(__FreeBSD__)
# define V8_OS_BSD 1
# define V8_OS_FREEBSD 1
# define V8_OS_POSIX 1
#elif defined(__DragonFly__)
# define V8_OS_BSD 1
# define V8_OS_DRAGONFLYBSD 1
# define V8_OS_POSIX 1
#elif defined(__NetBSD__)
# define V8_OS_BSD 1
# define V8_OS_NETBSD 1
# define V8_OS_POSIX 1
#elif defined(__OpenBSD__)
# define V8_OS_BSD 1
# define V8_OS_OPENBSD 1
# define V8_OS_POSIX 1
#elif defined(__QNXNTO__)
# define V8_OS_POSIX 1
# define V8_OS_QNX 1
#elif defined(_WIN32)
# define V8_OS_WIN 1
#endif
// -----------------------------------------------------------------------------
// C library detection
//
// V8_LIBC_MSVCRT - MSVC libc
// V8_LIBC_BIONIC - Bionic libc
// V8_LIBC_BSD - BSD libc derivate
// V8_LIBC_GLIBC - GNU C library
// V8_LIBC_UCLIBC - uClibc
//
// Note that testing for libc must be done using #if not #ifdef. For example,
// to test for the GNU C library, use:
// #if V8_LIBC_GLIBC
// ...
// #endif
#if defined (_MSC_VER)
# define V8_LIBC_MSVCRT 1
#elif defined(__BIONIC__)
# define V8_LIBC_BIONIC 1
# define V8_LIBC_BSD 1
#elif defined(__UCLIBC__)
// Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC.
# define V8_LIBC_UCLIBC 1
#elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
# define V8_LIBC_GLIBC 1
#else
# define V8_LIBC_BSD V8_OS_BSD
#endif
// -----------------------------------------------------------------------------
// Compiler detection
//
// V8_CC_GNU - GCC, or clang in gcc mode
// V8_CC_INTEL - Intel C++
// V8_CC_MINGW - Minimalist GNU for Windows
// V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
// V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
// V8_CC_MSVC - Microsoft Visual C/C++, or clang in cl.exe mode
//
// C++11 feature detection
//
// V8_HAS_CXX11_ALIGNAS - alignas specifier supported
// V8_HAS_CXX11_ALIGNOF - alignof(type) operator supported
//
// 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))
// supported
// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) 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_VISIBILITY - __attribute__((visibility)) supported
// V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
// supported
// V8_HAS_BUILTIN_CLZ - __builtin_clz() supported
// V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported
// V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported
// V8_HAS_BUILTIN_FRAME_ADDRESS - __builtin_frame_address() supported
// V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported
// V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported
// V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_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_NOINLINE - __declspec(noinline) supported
// V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported
// V8_HAS_DECLSPEC_NORETURN - __declspec(noreturn) supported
// V8_HAS___FORCEINLINE - __forceinline supported
//
// Note that testing for compilers and/or features must be done using #if
// not #ifdef. For example, to test for Intel C++ Compiler, use:
// #if V8_CC_INTEL
// ...
// #endif
#if defined(__clang__)
#if defined(__GNUC__) // Clang in gcc mode.
# define V8_CC_GNU 1
#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_DEPRECATED (__has_attribute(deprecated))
# 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_VISIBILITY (__has_attribute(visibility))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(__has_attribute(warn_unused_result))
# define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
# define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
# define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address))
# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
# define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_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_CXX11_ALIGNAS (__has_feature(cxx_alignas))
#elif defined(__GNUC__)
# define V8_CC_GNU 1
# if defined(__INTEL_COMPILER) // Intel C++ also masquerades as GCC 3.2.0
# define V8_CC_INTEL 1
# endif
# if defined(__MINGW32__)
# define V8_CC_MINGW32 1
# endif
# if defined(__MINGW64__)
# define V8_CC_MINGW64 1
# endif
# 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.
// Works around "sorry, unimplemented: inlining failed" build errors with
// older compilers.
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 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_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_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
(!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
# define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_BUILTIN_EXPECT (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))
# 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
#if defined(_MSC_VER)
# 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_NOINLINE 1
# define V8_HAS_DECLSPEC_SELECTANY 1
# define V8_HAS_DECLSPEC_NORETURN 1
# define V8_HAS___FORCEINLINE 1
#endif
// -----------------------------------------------------------------------------
// Helper macros
// A macro used to make better inlining. Don't bother for debug builds.
// Use like:
// V8_INLINE int GetZero() { return 0; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE
# define V8_INLINE inline __attribute__((always_inline))
#elif !defined(DEBUG) && V8_HAS___FORCEINLINE
# define V8_INLINE __forceinline
#else
# define V8_INLINE inline
#endif
// A macro used to tell the compiler to never inline a particular function.
// Don't bother for debug builds.
// Use like:
// V8_NOINLINE int GetMinusOne() { return -1; }
#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
# define V8_NOINLINE __attribute__((noinline))
#elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
# define V8_NOINLINE __declspec(noinline)
#else
# define V8_NOINLINE /* NOT SUPPORTED */
#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.
#if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATED(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATED(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATED(message, declarator) declarator
#endif
// A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated.
#if defined(V8_IMMINENT_DEPRECATION_WARNINGS) && \
V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated(message)))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) \
declarator __attribute__((deprecated))
#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED
#define V8_DEPRECATE_SOON(message, declarator) __declspec(deprecated) declarator
#else
#define V8_DEPRECATE_SOON(message, declarator) declarator
#endif
// A macro to provide the compiler with branch prediction information.
#if V8_HAS_BUILTIN_EXPECT
# define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
# define V8_LIKELY(condition) (__builtin_expect(!!(condition), 1))
#else
# define V8_UNLIKELY(condition) (condition)
# define V8_LIKELY(condition) (condition)
#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.
// Use like:
// int foo() WARN_UNUSED_RESULT;
#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
#define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
#endif
// clang-format on
#endif // V8CONFIG_H_

BIN
android/x86/libinspector.a Normal file

Binary file not shown.

BIN
android/x86/libv8_base.a Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
android/x86/libv8_libbase.a Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.