├── .github └── workflows │ └── main.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── deps ├── include │ ├── APIDesign.md │ ├── DEPS │ ├── DIR_METADATA │ ├── OWNERS │ ├── cppgc │ │ ├── DEPS │ │ ├── OWNERS │ │ ├── README.md │ │ ├── allocation.h │ │ ├── common.h │ │ ├── cross-thread-persistent.h │ │ ├── custom-space.h │ │ ├── default-platform.h │ │ ├── ephemeron-pair.h │ │ ├── explicit-management.h │ │ ├── garbage-collected.h │ │ ├── heap-consistency.h │ │ ├── heap-state.h │ │ ├── heap-statistics.h │ │ ├── heap.h │ │ ├── internal │ │ │ ├── api-constants.h │ │ │ ├── atomic-entry-flag.h │ │ │ ├── caged-heap-local-data.h │ │ │ ├── compiler-specific.h │ │ │ ├── finalizer-trait.h │ │ │ ├── gc-info.h │ │ │ ├── logging.h │ │ │ ├── name-trait.h │ │ │ ├── persistent-node.h │ │ │ ├── pointer-policies.h │ │ │ ├── prefinalizer-handler.h │ │ │ └── write-barrier.h │ │ ├── liveness-broker.h │ │ ├── macros.h │ │ ├── member.h │ │ ├── name-provider.h │ │ ├── object-size-trait.h │ │ ├── persistent.h │ │ ├── platform.h │ │ ├── prefinalizer.h │ │ ├── process-heap-statistics.h │ │ ├── sentinel-pointer.h │ │ ├── source-location.h │ │ ├── testing.h │ │ ├── trace-trait.h │ │ ├── type-traits.h │ │ └── visitor.h │ ├── js_protocol-1.2.json │ ├── js_protocol-1.3.json │ ├── js_protocol.pdl │ ├── libplatform │ │ ├── DEPS │ │ ├── libplatform-export.h │ │ ├── libplatform.h │ │ └── v8-tracing.h │ ├── v8-cppgc.h │ ├── v8-fast-api-calls.h │ ├── v8-inspector-protocol.h │ ├── v8-inspector.h │ ├── v8-internal.h │ ├── v8-metrics.h │ ├── v8-platform.h │ ├── v8-profiler.h │ ├── v8-unwinder-state.h │ ├── v8-util.h │ ├── v8-value-serializer-version.h │ ├── v8-version-string.h │ ├── v8-version.h │ ├── v8-wasm-trap-handler-posix.h │ ├── v8-wasm-trap-handler-win.h │ ├── v8.h │ └── v8config.h └── libv8_monolith.a ├── example ├── code.js ├── code.js.map └── code.ts └── src ├── Inspector.cpp ├── Inspector.h ├── main.cpp ├── utils.h ├── v8_inspector_listener_impl.h ├── v8inspector_channel.cpp ├── v8inspector_channel.h ├── v8inspector_client.cpp ├── v8inspector_client.h ├── v8inspector_listener.h ├── websocket_server.cpp └── websocket_server.h /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: C++ CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: check build dependencies 13 | run: | 14 | gcc --version 15 | cmake --version 16 | 17 | - name: prepare cmake 18 | run: | 19 | mkdir build 20 | cd build 21 | cmake ../ \ 22 | -DBOOST_ROOT=$BOOST_ROOT_1_72_0 \ 23 | -DBoost_ADDITIONAL_VERSIONS=1.72.0 \ 24 | -DV8_INCLUDE_DIR=$GITHUB_WORKSPACE/deps/include/ \ 25 | -DV8_MONOLITH_LIB_PATH=$GITHUB_WORKSPACE/deps/libv8_monolith.a 26 | 27 | - name: make 28 | run: | 29 | cd build 30 | make 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | 41 | # xemacs temporary files 42 | *.flc 43 | 44 | # Vim temporary files 45 | .*.swp 46 | 47 | # Visual Studio generated files 48 | *.ib_pdb_index 49 | *.idb 50 | *.ilk 51 | *.pdb 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Binaries 70 | # -------- 71 | *.dll 72 | *.exe 73 | 74 | # CMake output 75 | Debug 76 | 77 | .idea 78 | !deps/libv8_monolith.a 79 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(v8_inspector_example LANGUAGES CXX) 4 | 5 | set(CMAKE_CXX_STANDARD 14) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | 8 | set(V8_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/deps/include/" PATH "Path to the V8 include dir.") 9 | set(V8_MONOLITH_LIB_PATH "${CMAKE_SOURCE_DIR}/deps/libv8_monolith.a" ) 10 | set(BOOST_BEAST_INCLUDE "${BOOST_ROOT}/include" PATH "Path to the Boost.Beast include dir." ) 11 | 12 | FILE(GLOB TARGET_H "${CMAKE_SOURCE_DIR}/src/*.h") 13 | FILE(GLOB TARGET_CPP "${CMAKE_SOURCE_DIR}/src/*.cpp") 14 | SET(SOURCE_FILES ${TARGET_CPP} ${TARGET_H}) 15 | 16 | add_executable(v8_inspector_example ${SOURCE_FILES}) 17 | 18 | include_directories( 19 | ${V8_INCLUDE_DIR} 20 | ${BOOST_BEAST_INCLUDE} 21 | ) 22 | 23 | add_library(v8_monolith STATIC IMPORTED) 24 | set_target_properties( 25 | v8_monolith 26 | PROPERTIES 27 | IMPORTED_LOCATION 28 | "${V8_MONOLITH_LIB_PATH}" 29 | ) 30 | 31 | target_link_libraries(v8_inspector_example v8_monolith) 32 | target_link_libraries(v8_inspector_example pthread) 33 | target_link_libraries(v8_inspector_example stdc++fs) 34 | target_link_libraries(v8_inspector_example dl) 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Elmi Ahmadov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # V8 Inspector example 2 | 3 | This repository contains a very simple example how to use a standalone V8 Inspector (without Node.js) with ChromeDevTools. 4 | 5 | # Dependencies 6 | * V8 9.2.230.20 7 | * Boost.Beast (for WebSocket communication between ChromeDevTools and V8 Inspector) 8 | 9 | # Building 10 | ```shell 11 | $ mkdir build && cd build 12 | $ cmake -DV8_INCLUDE_DIR=../deps/include/ -DV8_MONOLITH_LIB_PATH=../deps/libv8_monolith.a ../ 13 | $ make 14 | 15 | # Execute the binary 16 | $ ./v8_inspector_example 17 | ``` 18 | -------------------------------------------------------------------------------- /deps/include/APIDesign.md: -------------------------------------------------------------------------------- 1 | # The V8 public C++ API 2 | 3 | # Overview 4 | 5 | The V8 public C++ API aims to support four use cases: 6 | 7 | 1. Enable applications that embed V8 (called the embedder) to configure and run 8 | one or more instances of V8. 9 | 2. Expose ECMAScript-like capabilities to the embedder. 10 | 3. Enable the embedder to interact with ECMAScript by exposing API objects. 11 | 4. Provide access to the V8 debugger (inspector). 12 | 13 | # Configuring and running an instance of V8 14 | 15 | V8 requires access to certain OS-level primitives such as the ability to 16 | schedule work on threads, or allocate memory. 17 | 18 | The embedder can define how to access those primitives via the v8::Platform 19 | interface. While V8 bundles a basic implementation, embedders are highly 20 | encouraged to implement v8::Platform themselves. 21 | 22 | Currently, the v8::ArrayBuffer::Allocator is passed to the v8::Isolate factory 23 | method, however, conceptually it should also be part of the v8::Platform since 24 | all instances of V8 should share one allocator. 25 | 26 | Once the v8::Platform is configured, an v8::Isolate can be created. All 27 | further interactions with V8 should explicitly reference the v8::Isolate they 28 | refer to. All API methods should eventually take an v8::Isolate parameter. 29 | 30 | When a given instance of V8 is no longer needed, it can be destroyed by 31 | disposing the respective v8::Isolate. If the embedder wishes to free all memory 32 | associated with the v8::Isolate, it has to first clear all global handles 33 | associated with that v8::Isolate. 34 | 35 | # ECMAScript-like capabilities 36 | 37 | In general, the C++ API shouldn't enable capabilities that aren't available to 38 | scripts running in V8. Experience has shown that it's not possible to maintain 39 | such API methods in the long term. However, capabilities also available to 40 | scripts, i.e., ones that are defined in the ECMAScript standard are there to 41 | stay, and we can safely expose them to embedders. 42 | 43 | The C++ API should also be pleasant to use, and not require learning new 44 | paradigms. Similarly to how the API exposed to scripts aims to provide good 45 | ergonomics, we should aim to provide a reasonable developer experience for this 46 | API surface. 47 | 48 | ECMAScript makes heavy use of exceptions, however, V8's C++ code doesn't use 49 | C++ exceptions. Therefore, all API methods that can throw exceptions should 50 | indicate so by returning a v8::Maybe<> or v8::MaybeLocal<> result, 51 | and by taking a v8::Local<v8::Context> parameter that indicates in which 52 | context a possible exception should be thrown. 53 | 54 | # API objects 55 | 56 | V8 allows embedders to define special objects that expose additional 57 | capabilities and APIs to scripts. The most prominent example is exposing the 58 | HTML DOM in Blink. Other examples are e.g. node.js. It is less clear what kind 59 | of capabilities we want to expose via this API surface. As a rule of thumb, we 60 | want to expose operations as defined in the WebIDL and HTML spec: we 61 | assume that those requirements are somewhat stable, and that they are a 62 | superset of the requirements of other embedders including node.js. 63 | 64 | Ideally, the API surfaces defined in those specs hook into the ECMAScript spec 65 | which in turn guarantees long-term stability of the API. 66 | 67 | # The V8 inspector 68 | 69 | All debugging capabilities of V8 should be exposed via the inspector protocol. 70 | The exception to this are profiling features exposed via v8-profiler.h. 71 | Changes to the inspector protocol need to ensure backwards compatibility and 72 | commitment to maintain. 73 | -------------------------------------------------------------------------------- /deps/include/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | # v8-inspector-protocol.h depends on generated files under include/inspector. 3 | "+inspector", 4 | "+cppgc/common.h", 5 | # Used by v8-cppgc.h to bridge to cppgc. 6 | "+cppgc/custom-space.h", 7 | "+cppgc/heap-statistics.h", 8 | "+cppgc/internal/write-barrier.h", 9 | "+cppgc/visitor.h", 10 | ] 11 | -------------------------------------------------------------------------------- /deps/include/DIR_METADATA: -------------------------------------------------------------------------------- 1 | # Metadata information for this directory. 2 | # 3 | # For more information on DIR_METADATA files, see: 4 | # https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md 5 | # 6 | # For the schema of this file, see Metadata message: 7 | # https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto 8 | 9 | monorail { 10 | component: "Blink>JavaScript>API" 11 | } -------------------------------------------------------------------------------- /deps/include/OWNERS: -------------------------------------------------------------------------------- 1 | adamk@chromium.org 2 | cbruni@chromium.org 3 | leszeks@chromium.org 4 | mlippautz@chromium.org 5 | ulan@chromium.org 6 | verwaest@chromium.org 7 | yangguo@chromium.org 8 | 9 | per-file *DEPS=file:../COMMON_OWNERS 10 | per-file v8-internal.h=file:../COMMON_OWNERS 11 | per-file v8-inspector.h=file:../src/inspector/OWNERS 12 | per-file v8-inspector-protocol.h=file:../src/inspector/OWNERS 13 | per-file js_protocol.pdl=file:../src/inspector/OWNERS 14 | 15 | # For branch updates: 16 | per-file v8-version.h=file:../INFRA_OWNERS 17 | per-file v8-version.h=hablich@chromium.org 18 | per-file v8-version.h=vahl@chromium.org 19 | -------------------------------------------------------------------------------- /deps/include/cppgc/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | "-include", 3 | "+v8config.h", 4 | "+v8-platform.h", 5 | "+cppgc", 6 | "-src", 7 | "+libplatform/libplatform.h", 8 | ] 9 | -------------------------------------------------------------------------------- /deps/include/cppgc/OWNERS: -------------------------------------------------------------------------------- 1 | bikineev@chromium.org 2 | omerkatz@chromium.org -------------------------------------------------------------------------------- /deps/include/cppgc/README.md: -------------------------------------------------------------------------------- 1 | # C++ Garbage Collection 2 | 3 | This directory provides an open-source garbage collection library for C++. 4 | 5 | The library is under construction, meaning that *all APIs in this directory are incomplete and considered unstable and should not be used*. -------------------------------------------------------------------------------- /deps/include/cppgc/allocation.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_ALLOCATION_H_ 6 | #define INCLUDE_CPPGC_ALLOCATION_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "cppgc/custom-space.h" 14 | #include "cppgc/garbage-collected.h" 15 | #include "cppgc/internal/api-constants.h" 16 | #include "cppgc/internal/gc-info.h" 17 | 18 | namespace cppgc { 19 | 20 | template 21 | class MakeGarbageCollectedTraitBase; 22 | 23 | namespace internal { 24 | class ObjectAllocator; 25 | } // namespace internal 26 | 27 | /** 28 | * AllocationHandle is used to allocate garbage-collected objects. 29 | */ 30 | class AllocationHandle; 31 | 32 | namespace internal { 33 | 34 | class V8_EXPORT MakeGarbageCollectedTraitInternal { 35 | protected: 36 | static inline void MarkObjectAsFullyConstructed(const void* payload) { 37 | // See api_constants for an explanation of the constants. 38 | std::atomic* atomic_mutable_bitfield = 39 | reinterpret_cast*>( 40 | const_cast(reinterpret_cast( 41 | reinterpret_cast(payload) - 42 | api_constants::kFullyConstructedBitFieldOffsetFromPayload))); 43 | atomic_mutable_bitfield->fetch_or(api_constants::kFullyConstructedBitMask, 44 | std::memory_order_release); 45 | } 46 | 47 | template 48 | struct SpacePolicy { 49 | static void* Allocate(AllocationHandle& handle, size_t size) { 50 | // Custom space. 51 | static_assert(std::is_base_of::value, 52 | "Custom space must inherit from CustomSpaceBase."); 53 | return MakeGarbageCollectedTraitInternal::Allocate( 54 | handle, size, internal::GCInfoTrait::Index(), 55 | CustomSpace::kSpaceIndex); 56 | } 57 | }; 58 | 59 | template 60 | struct SpacePolicy { 61 | static void* Allocate(AllocationHandle& handle, size_t size) { 62 | // Default space. 63 | return MakeGarbageCollectedTraitInternal::Allocate( 64 | handle, size, internal::GCInfoTrait::Index()); 65 | } 66 | }; 67 | 68 | private: 69 | static void* Allocate(cppgc::AllocationHandle& handle, size_t size, 70 | GCInfoIndex index); 71 | static void* Allocate(cppgc::AllocationHandle& handle, size_t size, 72 | GCInfoIndex index, CustomSpaceIndex space_index); 73 | 74 | friend class HeapObjectHeader; 75 | }; 76 | 77 | } // namespace internal 78 | 79 | /** 80 | * Base trait that provides utilities for advancers users that have custom 81 | * allocation needs (e.g., overriding size). It's expected that users override 82 | * MakeGarbageCollectedTrait (see below) and inherit from 83 | * MakeGarbageCollectedTraitBase and make use of the low-level primitives 84 | * offered to allocate and construct an object. 85 | */ 86 | template 87 | class MakeGarbageCollectedTraitBase 88 | : private internal::MakeGarbageCollectedTraitInternal { 89 | private: 90 | static_assert(internal::IsGarbageCollectedType::value, 91 | "T needs to be a garbage collected object"); 92 | static_assert(!IsGarbageCollectedWithMixinTypeV || 93 | sizeof(T) <= 94 | internal::api_constants::kLargeObjectSizeThreshold, 95 | "GarbageCollectedMixin may not be a large object"); 96 | 97 | protected: 98 | /** 99 | * Allocates memory for an object of type T. 100 | * 101 | * \param handle AllocationHandle identifying the heap to allocate the object 102 | * on. 103 | * \param size The size that should be reserved for the object. 104 | * \returns the memory to construct an object of type T on. 105 | */ 106 | V8_INLINE static void* Allocate(AllocationHandle& handle, size_t size) { 107 | static_assert( 108 | std::is_base_of::value, 109 | "U of GarbageCollected must be a base of T. Check " 110 | "GarbageCollected base class inheritance."); 111 | return SpacePolicy< 112 | typename internal::GCInfoFolding< 113 | T, typename T::ParentMostGarbageCollectedType>::ResultType, 114 | typename SpaceTrait::Space>::Allocate(handle, size); 115 | } 116 | 117 | /** 118 | * Marks an object as fully constructed, resulting in precise handling by the 119 | * garbage collector. 120 | * 121 | * \param payload The base pointer the object is allocated at. 122 | */ 123 | V8_INLINE static void MarkObjectAsFullyConstructed(const void* payload) { 124 | internal::MakeGarbageCollectedTraitInternal::MarkObjectAsFullyConstructed( 125 | payload); 126 | } 127 | }; 128 | 129 | /** 130 | * Passed to MakeGarbageCollected to specify how many bytes should be appended 131 | * to the allocated object. 132 | * 133 | * Example: 134 | * \code 135 | * class InlinedArray final : public GarbageCollected { 136 | * public: 137 | * explicit InlinedArray(size_t bytes) : size(bytes), byte_array(this + 1) {} 138 | * void Trace(Visitor*) const {} 139 | 140 | * size_t size; 141 | * char* byte_array; 142 | * }; 143 | * 144 | * auto* inlined_array = MakeGarbageCollectedbyte_array[i]); 148 | * } 149 | * \endcode 150 | */ 151 | struct AdditionalBytes { 152 | constexpr explicit AdditionalBytes(size_t bytes) : value(bytes) {} 153 | const size_t value; 154 | }; 155 | 156 | /** 157 | * Default trait class that specifies how to construct an object of type T. 158 | * Advanced users may override how an object is constructed using the utilities 159 | * that are provided through MakeGarbageCollectedTraitBase. 160 | * 161 | * Any trait overriding construction must 162 | * - allocate through `MakeGarbageCollectedTraitBase::Allocate`; 163 | * - mark the object as fully constructed using 164 | * `MakeGarbageCollectedTraitBase::MarkObjectAsFullyConstructed`; 165 | */ 166 | template 167 | class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase { 168 | public: 169 | template 170 | static T* Call(AllocationHandle& handle, Args&&... args) { 171 | void* memory = 172 | MakeGarbageCollectedTraitBase::Allocate(handle, sizeof(T)); 173 | T* object = ::new (memory) T(std::forward(args)...); 174 | MakeGarbageCollectedTraitBase::MarkObjectAsFullyConstructed(object); 175 | return object; 176 | } 177 | 178 | template 179 | static T* Call(AllocationHandle& handle, AdditionalBytes additional_bytes, 180 | Args&&... args) { 181 | void* memory = MakeGarbageCollectedTraitBase::Allocate( 182 | handle, sizeof(T) + additional_bytes.value); 183 | T* object = ::new (memory) T(std::forward(args)...); 184 | MakeGarbageCollectedTraitBase::MarkObjectAsFullyConstructed(object); 185 | return object; 186 | } 187 | }; 188 | 189 | /** 190 | * Allows users to specify a post-construction callback for specific types. The 191 | * callback is invoked on the instance of type T right after it has been 192 | * constructed. This can be useful when the callback requires a 193 | * fully-constructed object to be able to dispatch to virtual methods. 194 | */ 195 | template 196 | struct PostConstructionCallbackTrait { 197 | static void Call(T*) {} 198 | }; 199 | 200 | /** 201 | * Constructs a managed object of type T where T transitively inherits from 202 | * GarbageCollected. 203 | * 204 | * \param args List of arguments with which an instance of T will be 205 | * constructed. 206 | * \returns an instance of type T. 207 | */ 208 | template 209 | T* MakeGarbageCollected(AllocationHandle& handle, Args&&... args) { 210 | T* object = 211 | MakeGarbageCollectedTrait::Call(handle, std::forward(args)...); 212 | PostConstructionCallbackTrait::Call(object); 213 | return object; 214 | } 215 | 216 | /** 217 | * Constructs a managed object of type T where T transitively inherits from 218 | * GarbageCollected. Created objects will have additional bytes appended to 219 | * it. Allocated memory would suffice for `sizeof(T) + additional_bytes`. 220 | * 221 | * \param additional_bytes Denotes how many bytes to append to T. 222 | * \param args List of arguments with which an instance of T will be 223 | * constructed. 224 | * \returns an instance of type T. 225 | */ 226 | template 227 | T* MakeGarbageCollected(AllocationHandle& handle, 228 | AdditionalBytes additional_bytes, Args&&... args) { 229 | T* object = MakeGarbageCollectedTrait::Call(handle, additional_bytes, 230 | std::forward(args)...); 231 | PostConstructionCallbackTrait::Call(object); 232 | return object; 233 | } 234 | 235 | } // namespace cppgc 236 | 237 | #endif // INCLUDE_CPPGC_ALLOCATION_H_ 238 | -------------------------------------------------------------------------------- /deps/include/cppgc/common.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_COMMON_H_ 6 | #define INCLUDE_CPPGC_COMMON_H_ 7 | 8 | // TODO(chromium:1056170): Remove dependency on v8. 9 | #include "v8config.h" // NOLINT(build/include_directory) 10 | 11 | namespace cppgc { 12 | 13 | /** 14 | * Indicator for the stack state of the embedder. 15 | */ 16 | enum class EmbedderStackState { 17 | /** 18 | * Stack may contain interesting heap pointers. 19 | */ 20 | kMayContainHeapPointers, 21 | /** 22 | * Stack does not contain any interesting heap pointers. 23 | */ 24 | kNoHeapPointers, 25 | }; 26 | 27 | } // namespace cppgc 28 | 29 | #endif // INCLUDE_CPPGC_COMMON_H_ 30 | -------------------------------------------------------------------------------- /deps/include/cppgc/custom-space.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_CUSTOM_SPACE_H_ 6 | #define INCLUDE_CPPGC_CUSTOM_SPACE_H_ 7 | 8 | #include 9 | 10 | namespace cppgc { 11 | 12 | /** 13 | * Index identifying a custom space. 14 | */ 15 | struct CustomSpaceIndex { 16 | constexpr CustomSpaceIndex(size_t value) : value(value) {} // NOLINT 17 | size_t value; 18 | }; 19 | 20 | /** 21 | * Top-level base class for custom spaces. Users must inherit from CustomSpace 22 | * below. 23 | */ 24 | class CustomSpaceBase { 25 | public: 26 | virtual ~CustomSpaceBase() = default; 27 | virtual CustomSpaceIndex GetCustomSpaceIndex() const = 0; 28 | virtual bool IsCompactable() const = 0; 29 | }; 30 | 31 | /** 32 | * Base class custom spaces should directly inherit from. The class inheriting 33 | * from `CustomSpace` must define `kSpaceIndex` as unique space index. These 34 | * indices need for form a sequence starting at 0. 35 | * 36 | * Example: 37 | * \code 38 | * class CustomSpace1 : public CustomSpace { 39 | * public: 40 | * static constexpr CustomSpaceIndex kSpaceIndex = 0; 41 | * }; 42 | * class CustomSpace2 : public CustomSpace { 43 | * public: 44 | * static constexpr CustomSpaceIndex kSpaceIndex = 1; 45 | * }; 46 | * \endcode 47 | */ 48 | template 49 | class CustomSpace : public CustomSpaceBase { 50 | public: 51 | /** 52 | * Compaction is only supported on spaces that manually manage slots 53 | * recording. 54 | */ 55 | static constexpr bool kSupportsCompaction = false; 56 | 57 | CustomSpaceIndex GetCustomSpaceIndex() const final { 58 | return ConcreteCustomSpace::kSpaceIndex; 59 | } 60 | bool IsCompactable() const final { 61 | return ConcreteCustomSpace::kSupportsCompaction; 62 | } 63 | }; 64 | 65 | /** 66 | * User-overridable trait that allows pinning types to custom spaces. 67 | */ 68 | template 69 | struct SpaceTrait { 70 | using Space = void; 71 | }; 72 | 73 | namespace internal { 74 | 75 | template 76 | struct IsAllocatedOnCompactableSpaceImpl { 77 | static constexpr bool value = CustomSpace::kSupportsCompaction; 78 | }; 79 | 80 | template <> 81 | struct IsAllocatedOnCompactableSpaceImpl { 82 | // Non-custom spaces are by default not compactable. 83 | static constexpr bool value = false; 84 | }; 85 | 86 | template 87 | struct IsAllocatedOnCompactableSpace { 88 | public: 89 | static constexpr bool value = 90 | IsAllocatedOnCompactableSpaceImpl::Space>::value; 91 | }; 92 | 93 | } // namespace internal 94 | 95 | } // namespace cppgc 96 | 97 | #endif // INCLUDE_CPPGC_CUSTOM_SPACE_H_ 98 | -------------------------------------------------------------------------------- /deps/include/cppgc/default-platform.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_DEFAULT_PLATFORM_H_ 6 | #define INCLUDE_CPPGC_DEFAULT_PLATFORM_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "cppgc/platform.h" 12 | #include "libplatform/libplatform.h" 13 | #include "v8config.h" // NOLINT(build/include_directory) 14 | 15 | namespace cppgc { 16 | 17 | /** 18 | * Platform provided by cppgc. Uses V8's DefaultPlatform provided by 19 | * libplatform internally. Exception: `GetForegroundTaskRunner()`, see below. 20 | */ 21 | class V8_EXPORT DefaultPlatform : public Platform { 22 | public: 23 | /** 24 | * Use this method instead of 'cppgc::InitializeProcess' when using 25 | * 'cppgc::DefaultPlatform'. 'cppgc::DefaultPlatform::InitializeProcess' 26 | * will initialize cppgc and v8 if needed (for non-standalone builds). 27 | * 28 | * \param platform DefaultPlatform instance used to initialize cppgc/v8. 29 | */ 30 | static void InitializeProcess(DefaultPlatform* platform); 31 | 32 | using IdleTaskSupport = v8::platform::IdleTaskSupport; 33 | explicit DefaultPlatform( 34 | int thread_pool_size = 0, 35 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, 36 | std::unique_ptr tracing_controller = {}) 37 | : v8_platform_(v8::platform::NewDefaultPlatform( 38 | thread_pool_size, idle_task_support, 39 | v8::platform::InProcessStackDumping::kDisabled, 40 | std::move(tracing_controller))) {} 41 | 42 | cppgc::PageAllocator* GetPageAllocator() override { 43 | return v8_platform_->GetPageAllocator(); 44 | } 45 | 46 | double MonotonicallyIncreasingTime() override { 47 | return v8_platform_->MonotonicallyIncreasingTime(); 48 | } 49 | 50 | std::shared_ptr GetForegroundTaskRunner() override { 51 | // V8's default platform creates a new task runner when passed the 52 | // `v8::Isolate` pointer the first time. For non-default platforms this will 53 | // require getting the appropriate task runner. 54 | return v8_platform_->GetForegroundTaskRunner(kNoIsolate); 55 | } 56 | 57 | std::unique_ptr PostJob( 58 | cppgc::TaskPriority priority, 59 | std::unique_ptr job_task) override { 60 | return v8_platform_->PostJob(priority, std::move(job_task)); 61 | } 62 | 63 | TracingController* GetTracingController() override { 64 | return v8_platform_->GetTracingController(); 65 | } 66 | 67 | protected: 68 | static constexpr v8::Isolate* kNoIsolate = nullptr; 69 | 70 | std::unique_ptr v8_platform_; 71 | }; 72 | 73 | } // namespace cppgc 74 | 75 | #endif // INCLUDE_CPPGC_DEFAULT_PLATFORM_H_ 76 | -------------------------------------------------------------------------------- /deps/include/cppgc/ephemeron-pair.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_EPHEMERON_PAIR_H_ 6 | #define INCLUDE_CPPGC_EPHEMERON_PAIR_H_ 7 | 8 | #include "cppgc/liveness-broker.h" 9 | #include "cppgc/member.h" 10 | 11 | namespace cppgc { 12 | 13 | /** 14 | * An ephemeron pair is used to conditionally retain an object. 15 | * The `value` will be kept alive only if the `key` is alive. 16 | */ 17 | template 18 | struct EphemeronPair { 19 | EphemeronPair(K* k, V* v) : key(k), value(v) {} 20 | WeakMember key; 21 | Member value; 22 | 23 | void ClearValueIfKeyIsDead(const LivenessBroker& broker) { 24 | if (!broker.IsHeapObjectAlive(key)) value = nullptr; 25 | } 26 | }; 27 | 28 | } // namespace cppgc 29 | 30 | #endif // INCLUDE_CPPGC_EPHEMERON_PAIR_H_ 31 | -------------------------------------------------------------------------------- /deps/include/cppgc/explicit-management.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_ 6 | #define INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/allocation.h" 11 | #include "cppgc/internal/logging.h" 12 | #include "cppgc/type-traits.h" 13 | 14 | namespace cppgc { 15 | 16 | class HeapHandle; 17 | 18 | namespace internal { 19 | 20 | V8_EXPORT void FreeUnreferencedObject(HeapHandle&, void*); 21 | V8_EXPORT bool Resize(void*, size_t); 22 | 23 | } // namespace internal 24 | 25 | namespace subtle { 26 | 27 | /** 28 | * Informs the garbage collector that `object` can be immediately reclaimed. The 29 | * destructor may not be invoked immediately but only on next garbage 30 | * collection. 31 | * 32 | * It is up to the embedder to guarantee that no other object holds a reference 33 | * to `object` after calling `FreeUnreferencedObject()`. In case such a 34 | * reference exists, it's use results in a use-after-free. 35 | * 36 | * To aid in using the API, `FreeUnreferencedObject()` may be called from 37 | * destructors on objects that would be reclaimed in the same garbage collection 38 | * cycle. 39 | * 40 | * \param heap_handle The corresponding heap. 41 | * \param object Reference to an object that is of type `GarbageCollected` and 42 | * should be immediately reclaimed. 43 | */ 44 | template 45 | void FreeUnreferencedObject(HeapHandle& heap_handle, T& object) { 46 | static_assert(IsGarbageCollectedTypeV, 47 | "Object must be of type GarbageCollected."); 48 | internal::FreeUnreferencedObject(heap_handle, &object); 49 | } 50 | 51 | /** 52 | * Tries to resize `object` of type `T` with additional bytes on top of 53 | * sizeof(T). Resizing is only useful with trailing inlined storage, see e.g. 54 | * `MakeGarbageCollected(AllocationHandle&, AdditionalBytes)`. 55 | * 56 | * `Resize()` performs growing or shrinking as needed and may skip the operation 57 | * for internal reasons, see return value. 58 | * 59 | * It is up to the embedder to guarantee that in case of shrinking a larger 60 | * object down, the reclaimed area is not used anymore. Any subsequent use 61 | * results in a use-after-free. 62 | * 63 | * The `object` must be live when calling `Resize()`. 64 | * 65 | * \param object Reference to an object that is of type `GarbageCollected` and 66 | * should be resized. 67 | * \param additional_bytes Bytes in addition to sizeof(T) that the object should 68 | * provide. 69 | * \returns true when the operation was successful and the result can be relied 70 | * on, and false otherwise. 71 | */ 72 | template 73 | bool Resize(T& object, AdditionalBytes additional_bytes) { 74 | static_assert(IsGarbageCollectedTypeV, 75 | "Object must be of type GarbageCollected."); 76 | return internal::Resize(&object, sizeof(T) + additional_bytes.value); 77 | } 78 | 79 | } // namespace subtle 80 | } // namespace cppgc 81 | 82 | #endif // INCLUDE_CPPGC_EXPLICIT_MANAGEMENT_H_ 83 | -------------------------------------------------------------------------------- /deps/include/cppgc/garbage-collected.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_GARBAGE_COLLECTED_H_ 6 | #define INCLUDE_CPPGC_GARBAGE_COLLECTED_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/internal/api-constants.h" 11 | #include "cppgc/platform.h" 12 | #include "cppgc/trace-trait.h" 13 | #include "cppgc/type-traits.h" 14 | 15 | namespace cppgc { 16 | 17 | class Visitor; 18 | 19 | namespace internal { 20 | 21 | class GarbageCollectedBase { 22 | public: 23 | // Must use MakeGarbageCollected. 24 | void* operator new(size_t) = delete; 25 | void* operator new[](size_t) = delete; 26 | // The garbage collector is taking care of reclaiming the object. Also, 27 | // virtual destructor requires an unambiguous, accessible 'operator delete'. 28 | void operator delete(void*) { 29 | #ifdef V8_ENABLE_CHECKS 30 | internal::Abort(); 31 | #endif // V8_ENABLE_CHECKS 32 | } 33 | void operator delete[](void*) = delete; 34 | 35 | protected: 36 | GarbageCollectedBase() = default; 37 | }; 38 | 39 | } // namespace internal 40 | 41 | /** 42 | * Base class for managed objects. Only descendent types of `GarbageCollected` 43 | * can be constructed using `MakeGarbageCollected()`. Must be inherited from as 44 | * left-most base class. 45 | * 46 | * Types inheriting from GarbageCollected must provide a method of 47 | * signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed 48 | * pointers to the visitor and delegates to garbage-collected base classes. 49 | * The method must be virtual if the type is not directly a child of 50 | * GarbageCollected and marked as final. 51 | * 52 | * \code 53 | * // Example using final class. 54 | * class FinalType final : public GarbageCollected { 55 | * public: 56 | * void Trace(cppgc::Visitor* visitor) const { 57 | * // Dispatch using visitor->Trace(...); 58 | * } 59 | * }; 60 | * 61 | * // Example using non-final base class. 62 | * class NonFinalBase : public GarbageCollected { 63 | * public: 64 | * virtual void Trace(cppgc::Visitor*) const {} 65 | * }; 66 | * 67 | * class FinalChild final : public NonFinalBase { 68 | * public: 69 | * void Trace(cppgc::Visitor* visitor) const final { 70 | * // Dispatch using visitor->Trace(...); 71 | * NonFinalBase::Trace(visitor); 72 | * } 73 | * }; 74 | * \endcode 75 | */ 76 | template 77 | class GarbageCollected : public internal::GarbageCollectedBase { 78 | public: 79 | using IsGarbageCollectedTypeMarker = void; 80 | using ParentMostGarbageCollectedType = T; 81 | 82 | protected: 83 | GarbageCollected() = default; 84 | }; 85 | 86 | /** 87 | * Base class for managed mixin objects. Such objects cannot be constructed 88 | * directly but must be mixed into the inheritance hierarchy of a 89 | * GarbageCollected object. 90 | * 91 | * Types inheriting from GarbageCollectedMixin must override a virtual method 92 | * of signature `void Trace(cppgc::Visitor*) const` that dispatchs all managed 93 | * pointers to the visitor and delegates to base classes. 94 | * 95 | * \code 96 | * class Mixin : public GarbageCollectedMixin { 97 | * public: 98 | * void Trace(cppgc::Visitor* visitor) const override { 99 | * // Dispatch using visitor->Trace(...); 100 | * } 101 | * }; 102 | * \endcode 103 | */ 104 | class GarbageCollectedMixin : public internal::GarbageCollectedBase { 105 | public: 106 | using IsGarbageCollectedMixinTypeMarker = void; 107 | 108 | /** 109 | * This Trace method must be overriden by objects inheriting from 110 | * GarbageCollectedMixin. 111 | */ 112 | virtual void Trace(cppgc::Visitor*) const {} 113 | }; 114 | 115 | } // namespace cppgc 116 | 117 | #endif // INCLUDE_CPPGC_GARBAGE_COLLECTED_H_ 118 | -------------------------------------------------------------------------------- /deps/include/cppgc/heap-consistency.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ 6 | #define INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/internal/write-barrier.h" 11 | #include "cppgc/macros.h" 12 | #include "cppgc/trace-trait.h" 13 | #include "v8config.h" // NOLINT(build/include_directory) 14 | 15 | namespace cppgc { 16 | 17 | class HeapHandle; 18 | 19 | namespace subtle { 20 | 21 | /** 22 | * **DO NOT USE: Use the appropriate managed types.** 23 | * 24 | * Consistency helpers that aid in maintaining a consistent internal state of 25 | * the garbage collector. 26 | */ 27 | class HeapConsistency final { 28 | public: 29 | using WriteBarrierParams = internal::WriteBarrier::Params; 30 | using WriteBarrierType = internal::WriteBarrier::Type; 31 | 32 | /** 33 | * Gets the required write barrier type for a specific write. 34 | * 35 | * \param slot Slot containing the pointer to the object. The slot itself 36 | * must reside in an object that has been allocated using 37 | * `MakeGarbageCollected()`. 38 | * \param value The pointer to the object. May be an interior pointer to an 39 | * interface of the actual object. 40 | * \param params Parameters that may be used for actual write barrier calls. 41 | * Only filled if return value indicates that a write barrier is needed. The 42 | * contents of the `params` are an implementation detail. 43 | * \returns whether a write barrier is needed and which barrier to invoke. 44 | */ 45 | static V8_INLINE WriteBarrierType GetWriteBarrierType( 46 | const void* slot, const void* value, WriteBarrierParams& params) { 47 | return internal::WriteBarrier::GetWriteBarrierType(slot, value, params); 48 | } 49 | 50 | /** 51 | * Gets the required write barrier type for a specific write. 52 | * 53 | * \param slot Slot to some part of an object. The object must not necessarily 54 | have been allocated using `MakeGarbageCollected()` but can also live 55 | off-heap or on stack. 56 | * \param params Parameters that may be used for actual write barrier calls. 57 | * Only filled if return value indicates that a write barrier is needed. The 58 | * contents of the `params` are an implementation detail. 59 | * \param callback Callback returning the corresponding heap handle. The 60 | * callback is only invoked if the heap cannot otherwise be figured out. The 61 | * callback must not allocate. 62 | * \returns whether a write barrier is needed and which barrier to invoke. 63 | */ 64 | template 65 | static V8_INLINE WriteBarrierType 66 | GetWriteBarrierType(const void* slot, WriteBarrierParams& params, 67 | HeapHandleCallback callback) { 68 | return internal::WriteBarrier::GetWriteBarrierType(slot, params, callback); 69 | } 70 | 71 | /** 72 | * Conservative Dijkstra-style write barrier that processes an object if it 73 | * has not yet been processed. 74 | * 75 | * \param params The parameters retrieved from `GetWriteBarrierType()`. 76 | * \param object The pointer to the object. May be an interior pointer to a 77 | * an interface of the actual object. 78 | */ 79 | static V8_INLINE void DijkstraWriteBarrier(const WriteBarrierParams& params, 80 | const void* object) { 81 | internal::WriteBarrier::DijkstraMarkingBarrier(params, object); 82 | } 83 | 84 | /** 85 | * Conservative Dijkstra-style write barrier that processes a range of 86 | * elements if they have not yet been processed. 87 | * 88 | * \param params The parameters retrieved from `GetWriteBarrierType()`. 89 | * \param first_element Pointer to the first element that should be processed. 90 | * The slot itself must reside in an object that has been allocated using 91 | * `MakeGarbageCollected()`. 92 | * \param element_size Size of the element in bytes. 93 | * \param number_of_elements Number of elements that should be processed, 94 | * starting with `first_element`. 95 | * \param trace_callback The trace callback that should be invoked for each 96 | * element if necessary. 97 | */ 98 | static V8_INLINE void DijkstraWriteBarrierRange( 99 | const WriteBarrierParams& params, const void* first_element, 100 | size_t element_size, size_t number_of_elements, 101 | TraceCallback trace_callback) { 102 | internal::WriteBarrier::DijkstraMarkingBarrierRange( 103 | params, first_element, element_size, number_of_elements, 104 | trace_callback); 105 | } 106 | 107 | /** 108 | * Steele-style write barrier that re-processes an object if it has already 109 | * been processed. 110 | * 111 | * \param params The parameters retrieved from `GetWriteBarrierType()`. 112 | * \param object The pointer to the object which must point to an object that 113 | * has been allocated using `MakeGarbageCollected()`. Interior pointers are 114 | * not supported. 115 | */ 116 | static V8_INLINE void SteeleWriteBarrier(const WriteBarrierParams& params, 117 | const void* object) { 118 | internal::WriteBarrier::SteeleMarkingBarrier(params, object); 119 | } 120 | 121 | /** 122 | * Generational barrier for maintaining consistency when running with multiple 123 | * generations. 124 | * 125 | * \param params The parameters retrieved from `GetWriteBarrierType()`. 126 | * \param slot Slot containing the pointer to the object. The slot itself 127 | * must reside in an object that has been allocated using 128 | * `MakeGarbageCollected()`. 129 | */ 130 | static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params, 131 | const void* slot) { 132 | internal::WriteBarrier::GenerationalBarrier(params, slot); 133 | } 134 | 135 | private: 136 | HeapConsistency() = delete; 137 | }; 138 | 139 | /** 140 | * Disallows garbage collection finalizations. Any garbage collection triggers 141 | * result in a crash when in this scope. 142 | * 143 | * Note that the garbage collector already covers paths that can lead to garbage 144 | * collections, so user code does not require checking 145 | * `IsGarbageCollectionAllowed()` before allocations. 146 | */ 147 | class V8_EXPORT V8_NODISCARD DisallowGarbageCollectionScope final { 148 | CPPGC_STACK_ALLOCATED(); 149 | 150 | public: 151 | /** 152 | * \returns whether garbage collections are currently allowed. 153 | */ 154 | static bool IsGarbageCollectionAllowed(HeapHandle& heap_handle); 155 | 156 | /** 157 | * Enters a disallow garbage collection scope. Must be paired with `Leave()`. 158 | * Prefer a scope instance of `DisallowGarbageCollectionScope`. 159 | * 160 | * \param heap_handle The corresponding heap. 161 | */ 162 | static void Enter(HeapHandle& heap_handle); 163 | 164 | /** 165 | * Leaves a disallow garbage collection scope. Must be paired with `Enter()`. 166 | * Prefer a scope instance of `DisallowGarbageCollectionScope`. 167 | * 168 | * \param heap_handle The corresponding heap. 169 | */ 170 | static void Leave(HeapHandle& heap_handle); 171 | 172 | /** 173 | * Constructs a scoped object that automatically enters and leaves a disallow 174 | * garbage collection scope based on its lifetime. 175 | * 176 | * \param heap_handle The corresponding heap. 177 | */ 178 | explicit DisallowGarbageCollectionScope(HeapHandle& heap_handle); 179 | ~DisallowGarbageCollectionScope(); 180 | 181 | DisallowGarbageCollectionScope(const DisallowGarbageCollectionScope&) = 182 | delete; 183 | DisallowGarbageCollectionScope& operator=( 184 | const DisallowGarbageCollectionScope&) = delete; 185 | 186 | private: 187 | HeapHandle& heap_handle_; 188 | }; 189 | 190 | /** 191 | * Avoids invoking garbage collection finalizations. Already running garbage 192 | * collection phase are unaffected by this scope. 193 | * 194 | * Should only be used temporarily as the scope has an impact on memory usage 195 | * and follow up garbage collections. 196 | */ 197 | class V8_EXPORT V8_NODISCARD NoGarbageCollectionScope final { 198 | CPPGC_STACK_ALLOCATED(); 199 | 200 | public: 201 | /** 202 | * Enters a no garbage collection scope. Must be paired with `Leave()`. Prefer 203 | * a scope instance of `NoGarbageCollectionScope`. 204 | * 205 | * \param heap_handle The corresponding heap. 206 | */ 207 | static void Enter(HeapHandle& heap_handle); 208 | 209 | /** 210 | * Leaves a no garbage collection scope. Must be paired with `Enter()`. Prefer 211 | * a scope instance of `NoGarbageCollectionScope`. 212 | * 213 | * \param heap_handle The corresponding heap. 214 | */ 215 | static void Leave(HeapHandle& heap_handle); 216 | 217 | /** 218 | * Constructs a scoped object that automatically enters and leaves a no 219 | * garbage collection scope based on its lifetime. 220 | * 221 | * \param heap_handle The corresponding heap. 222 | */ 223 | explicit NoGarbageCollectionScope(HeapHandle& heap_handle); 224 | ~NoGarbageCollectionScope(); 225 | 226 | NoGarbageCollectionScope(const NoGarbageCollectionScope&) = delete; 227 | NoGarbageCollectionScope& operator=(const NoGarbageCollectionScope&) = delete; 228 | 229 | private: 230 | HeapHandle& heap_handle_; 231 | }; 232 | 233 | } // namespace subtle 234 | } // namespace cppgc 235 | 236 | #endif // INCLUDE_CPPGC_HEAP_CONSISTENCY_H_ 237 | -------------------------------------------------------------------------------- /deps/include/cppgc/heap-state.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_HEAP_STATE_H_ 6 | #define INCLUDE_CPPGC_HEAP_STATE_H_ 7 | 8 | #include "v8config.h" // NOLINT(build/include_directory) 9 | 10 | namespace cppgc { 11 | 12 | class HeapHandle; 13 | 14 | namespace subtle { 15 | 16 | /** 17 | * Helpers to peek into heap-internal state. 18 | */ 19 | class V8_EXPORT HeapState final { 20 | public: 21 | /** 22 | * Returns whether the garbage collector is marking. This API is experimental 23 | * and is expected to be removed in future. 24 | * 25 | * \param heap_handle The corresponding heap. 26 | * \returns true if the garbage collector is currently marking, and false 27 | * otherwise. 28 | */ 29 | static bool IsMarking(const HeapHandle& heap_handle); 30 | 31 | /* 32 | * Returns whether the garbage collector is sweeping. This API is experimental 33 | * and is expected to be removed in future. 34 | * 35 | * \param heap_handle The corresponding heap. 36 | * \returns true if the garbage collector is currently sweeping, and false 37 | * otherwise. 38 | */ 39 | static bool IsSweeping(const HeapHandle& heap_handle); 40 | 41 | /** 42 | * Returns whether the garbage collector is in the atomic pause, i.e., the 43 | * mutator is stopped from running. This API is experimental and is expected 44 | * to be removed in future. 45 | * 46 | * \param heap_handle The corresponding heap. 47 | * \returns true if the garbage collector is currently in the atomic pause, 48 | * and false otherwise. 49 | */ 50 | static bool IsInAtomicPause(const HeapHandle& heap_handle); 51 | 52 | /** 53 | * Returns whether the last garbage collection was finalized conservatively 54 | * (i.e., with a non-empty stack). This API is experimental and is expected to 55 | * be removed in future. 56 | * 57 | * \param heap_handle The corresponding heap. 58 | * \returns true if the last garbage collection was finalized conservatively, 59 | * and false otherwise. 60 | */ 61 | static bool PreviousGCWasConservative(const HeapHandle& heap_handle); 62 | 63 | private: 64 | HeapState() = delete; 65 | }; 66 | 67 | } // namespace subtle 68 | } // namespace cppgc 69 | 70 | #endif // INCLUDE_CPPGC_HEAP_STATE_H_ 71 | -------------------------------------------------------------------------------- /deps/include/cppgc/heap-statistics.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_HEAP_STATISTICS_H_ 6 | #define INCLUDE_CPPGC_HEAP_STATISTICS_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace cppgc { 13 | 14 | /** 15 | * `HeapStatistics` contains memory consumption and utilization statistics for a 16 | * cppgc heap. 17 | */ 18 | struct HeapStatistics final { 19 | /** 20 | * Specifies the detail level of the heap statistics. Brief statistics contain 21 | * only the top-level allocated and used memory statistics for the entire 22 | * heap. Detailed statistics also contain a break down per space and page, as 23 | * well as freelist statistics and object type histograms. Note that used 24 | * memory reported by brief statistics and detailed statistics might differ 25 | * slightly. 26 | */ 27 | enum DetailLevel : uint8_t { 28 | kBrief, 29 | kDetailed, 30 | }; 31 | 32 | /** 33 | * Statistics of object types. For each type the statistics record its name, 34 | * how many objects of that type were allocated, and the overall size used by 35 | * these objects. 36 | */ 37 | struct ObjectStatistics { 38 | /** Number of distinct types in the heap. */ 39 | size_t num_types = 0; 40 | /** Name of each type in the heap. */ 41 | std::vector type_name; 42 | /** Number of allocated objects per each type. */ 43 | std::vector type_count; 44 | /** Overall size of allocated objects per each type. */ 45 | std::vector type_bytes; 46 | }; 47 | 48 | /** 49 | * Page granularity statistics. For each page the statistics record the 50 | * allocated memory size and overall used memory size for the page. 51 | */ 52 | struct PageStatistics { 53 | /** Overall amount of memory allocated for the page. */ 54 | size_t physical_size_bytes = 0; 55 | /** Amount of memory actually used on the page. */ 56 | size_t used_size_bytes = 0; 57 | }; 58 | 59 | /** 60 | * Statistics of the freelist (used only in non-large object spaces). For 61 | * each bucket in the freelist the statistics record the bucket size, the 62 | * number of freelist entries in the bucket, and the overall allocated memory 63 | * consumed by these freelist entries. 64 | */ 65 | struct FreeListStatistics { 66 | /** bucket sizes in the freelist. */ 67 | std::vector bucket_size; 68 | /** number of freelist entries per bucket. */ 69 | std::vector free_count; 70 | /** memory size consumed by freelist entries per size. */ 71 | std::vector free_size; 72 | }; 73 | 74 | /** 75 | * Space granularity statistics. For each space the statistics record the 76 | * space name, the amount of allocated memory and overall used memory for the 77 | * space. The statistics also contain statistics for each of the space's 78 | * pages, its freelist and the objects allocated on the space. 79 | */ 80 | struct SpaceStatistics { 81 | /** The space name */ 82 | std::string name; 83 | /** Overall amount of memory allocated for the space. */ 84 | size_t physical_size_bytes = 0; 85 | /** Amount of memory actually used on the space. */ 86 | size_t used_size_bytes = 0; 87 | /** Statistics for each of the pages in the space. */ 88 | std::vector page_stats; 89 | /** Statistics for the freelist of the space. */ 90 | FreeListStatistics free_list_stats; 91 | /** Statistics for object allocated on the space. Filled only when 92 | * NameProvider::HideInternalNames() is false. */ 93 | ObjectStatistics object_stats; 94 | }; 95 | 96 | /** Overall amount of memory allocated for the heap. */ 97 | size_t physical_size_bytes = 0; 98 | /** Amount of memory actually used on the heap. */ 99 | size_t used_size_bytes = 0; 100 | /** Detail level of this HeapStatistics. */ 101 | DetailLevel detail_level; 102 | 103 | /** Statistics for each of the spaces in the heap. Filled only when 104 | * detail_level is kDetailed. */ 105 | std::vector space_stats; 106 | }; 107 | 108 | } // namespace cppgc 109 | 110 | #endif // INCLUDE_CPPGC_HEAP_STATISTICS_H_ 111 | -------------------------------------------------------------------------------- /deps/include/cppgc/heap.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_HEAP_H_ 6 | #define INCLUDE_CPPGC_HEAP_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "cppgc/common.h" 12 | #include "cppgc/custom-space.h" 13 | #include "cppgc/platform.h" 14 | #include "v8config.h" // NOLINT(build/include_directory) 15 | 16 | /** 17 | * cppgc - A C++ garbage collection library. 18 | */ 19 | namespace cppgc { 20 | 21 | class AllocationHandle; 22 | 23 | /** 24 | * Implementation details of cppgc. Those details are considered internal and 25 | * may change at any point in time without notice. Users should never rely on 26 | * the contents of this namespace. 27 | */ 28 | namespace internal { 29 | class Heap; 30 | } // namespace internal 31 | 32 | /** 33 | * Used for additional heap APIs. 34 | */ 35 | class HeapHandle; 36 | 37 | class V8_EXPORT Heap { 38 | public: 39 | /** 40 | * Specifies the stack state the embedder is in. 41 | */ 42 | using StackState = EmbedderStackState; 43 | 44 | /** 45 | * Specifies whether conservative stack scanning is supported. 46 | */ 47 | enum class StackSupport : uint8_t { 48 | /** 49 | * Conservative stack scan is supported. 50 | */ 51 | kSupportsConservativeStackScan, 52 | /** 53 | * Conservative stack scan is not supported. Embedders may use this option 54 | * when using custom infrastructure that is unsupported by the library. 55 | */ 56 | kNoConservativeStackScan, 57 | }; 58 | 59 | /** 60 | * Specifies supported marking types 61 | */ 62 | enum class MarkingType : uint8_t { 63 | /** 64 | * Atomic stop-the-world marking. This option does not require any write 65 | * barriers but is the most intrusive in terms of jank. 66 | */ 67 | kAtomic, 68 | /** 69 | * Incremental marking, i.e. interleave marking is the rest of the 70 | * application on the same thread. 71 | */ 72 | kIncremental, 73 | /** 74 | * Incremental and concurrent marking. 75 | */ 76 | kIncrementalAndConcurrent 77 | }; 78 | 79 | /** 80 | * Specifies supported sweeping types 81 | */ 82 | enum class SweepingType : uint8_t { 83 | /** 84 | * Atomic stop-the-world sweeping. All of sweeping is performed at once. 85 | */ 86 | kAtomic, 87 | /** 88 | * Incremental and concurrent sweeping. Sweeping is split and interleaved 89 | * with the rest of the application. 90 | */ 91 | kIncrementalAndConcurrent 92 | }; 93 | 94 | /** 95 | * Constraints for a Heap setup. 96 | */ 97 | struct ResourceConstraints { 98 | /** 99 | * Allows the heap to grow to some initial size in bytes before triggering 100 | * garbage collections. This is useful when it is known that applications 101 | * need a certain minimum heap to run to avoid repeatedly invoking the 102 | * garbage collector when growing the heap. 103 | */ 104 | size_t initial_heap_size_bytes = 0; 105 | }; 106 | 107 | /** 108 | * Options specifying Heap properties (e.g. custom spaces) when initializing a 109 | * heap through `Heap::Create()`. 110 | */ 111 | struct HeapOptions { 112 | /** 113 | * Creates reasonable defaults for instantiating a Heap. 114 | * 115 | * \returns the HeapOptions that can be passed to `Heap::Create()`. 116 | */ 117 | static HeapOptions Default() { return {}; } 118 | 119 | /** 120 | * Custom spaces added to heap are required to have indices forming a 121 | * numbered sequence starting at 0, i.e., their `kSpaceIndex` must 122 | * correspond to the index they reside in the vector. 123 | */ 124 | std::vector> custom_spaces; 125 | 126 | /** 127 | * Specifies whether conservative stack scan is supported. When conservative 128 | * stack scan is not supported, the collector may try to invoke 129 | * garbage collections using non-nestable task, which are guaranteed to have 130 | * no interesting stack, through the provided Platform. If such tasks are 131 | * not supported by the Platform, the embedder must take care of invoking 132 | * the GC through `ForceGarbageCollectionSlow()`. 133 | */ 134 | StackSupport stack_support = StackSupport::kSupportsConservativeStackScan; 135 | 136 | /** 137 | * Specifies which types of marking are supported by the heap. 138 | */ 139 | MarkingType marking_support = MarkingType::kIncrementalAndConcurrent; 140 | 141 | /** 142 | * Specifies which types of sweeping are supported by the heap. 143 | */ 144 | SweepingType sweeping_support = SweepingType::kIncrementalAndConcurrent; 145 | 146 | /** 147 | * Resource constraints specifying various properties that the internal 148 | * GC scheduler follows. 149 | */ 150 | ResourceConstraints resource_constraints; 151 | }; 152 | 153 | /** 154 | * Creates a new heap that can be used for object allocation. 155 | * 156 | * \param platform implemented and provided by the embedder. 157 | * \param options HeapOptions specifying various properties for the Heap. 158 | * \returns a new Heap instance. 159 | */ 160 | static std::unique_ptr Create( 161 | std::shared_ptr platform, 162 | HeapOptions options = HeapOptions::Default()); 163 | 164 | virtual ~Heap() = default; 165 | 166 | /** 167 | * Forces garbage collection. 168 | * 169 | * \param source String specifying the source (or caller) triggering a 170 | * forced garbage collection. 171 | * \param reason String specifying the reason for the forced garbage 172 | * collection. 173 | * \param stack_state The embedder stack state, see StackState. 174 | */ 175 | void ForceGarbageCollectionSlow( 176 | const char* source, const char* reason, 177 | StackState stack_state = StackState::kMayContainHeapPointers); 178 | 179 | /** 180 | * \returns the opaque handle for allocating objects using 181 | * `MakeGarbageCollected()`. 182 | */ 183 | AllocationHandle& GetAllocationHandle(); 184 | 185 | /** 186 | * \returns the opaque heap handle which may be used to refer to this heap in 187 | * other APIs. Valid as long as the underlying `Heap` is alive. 188 | */ 189 | HeapHandle& GetHeapHandle(); 190 | 191 | private: 192 | Heap() = default; 193 | 194 | friend class internal::Heap; 195 | }; 196 | 197 | } // namespace cppgc 198 | 199 | #endif // INCLUDE_CPPGC_HEAP_H_ 200 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/api-constants.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_API_CONSTANTS_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_API_CONSTANTS_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "v8config.h" // NOLINT(build/include_directory) 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | // Embedders should not rely on this code! 17 | 18 | // Internal constants to avoid exposing internal types on the API surface. 19 | namespace api_constants { 20 | 21 | constexpr size_t kKB = 1024; 22 | constexpr size_t kMB = kKB * 1024; 23 | constexpr size_t kGB = kMB * 1024; 24 | 25 | // Offset of the uint16_t bitfield from the payload contaning the 26 | // in-construction bit. This is subtracted from the payload pointer to get 27 | // to the right bitfield. 28 | static constexpr size_t kFullyConstructedBitFieldOffsetFromPayload = 29 | 2 * sizeof(uint16_t); 30 | // Mask for in-construction bit. 31 | static constexpr uint16_t kFullyConstructedBitMask = uint16_t{1}; 32 | 33 | static constexpr size_t kPageSize = size_t{1} << 17; 34 | 35 | static constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2; 36 | 37 | #if defined(CPPGC_CAGED_HEAP) 38 | constexpr size_t kCagedHeapReservationSize = static_cast(4) * kGB; 39 | constexpr size_t kCagedHeapReservationAlignment = kCagedHeapReservationSize; 40 | #endif 41 | 42 | } // namespace api_constants 43 | 44 | } // namespace internal 45 | } // namespace cppgc 46 | 47 | #endif // INCLUDE_CPPGC_INTERNAL_API_CONSTANTS_H_ 48 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/atomic-entry-flag.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_ 7 | 8 | #include 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | // A flag which provides a fast check whether a scope may be entered on the 14 | // current thread, without needing to access thread-local storage or mutex. Can 15 | // have false positives (i.e., spuriously report that it might be entered), so 16 | // it is expected that this will be used in tandem with a precise check that the 17 | // scope is in fact entered on that thread. 18 | // 19 | // Example: 20 | // g_frobnicating_flag.MightBeEntered() && 21 | // ThreadLocalFrobnicator().IsFrobnicating() 22 | // 23 | // Relaxed atomic operations are sufficient, since: 24 | // - all accesses remain atomic 25 | // - each thread must observe its own operations in order 26 | // - no thread ever exits the flag more times than it enters (if used correctly) 27 | // And so if a thread observes zero, it must be because it has observed an equal 28 | // number of exits as entries. 29 | class AtomicEntryFlag final { 30 | public: 31 | void Enter() { entries_.fetch_add(1, std::memory_order_relaxed); } 32 | void Exit() { entries_.fetch_sub(1, std::memory_order_relaxed); } 33 | 34 | // Returns false only if the current thread is not between a call to Enter 35 | // and a call to Exit. Returns true if this thread or another thread may 36 | // currently be in the scope guarded by this flag. 37 | bool MightBeEntered() const { 38 | return entries_.load(std::memory_order_relaxed) != 0; 39 | } 40 | 41 | private: 42 | std::atomic_int entries_{0}; 43 | }; 44 | 45 | } // namespace internal 46 | } // namespace cppgc 47 | 48 | #endif // INCLUDE_CPPGC_INTERNAL_ATOMIC_ENTRY_FLAG_H_ 49 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/caged-heap-local-data.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/internal/api-constants.h" 11 | #include "cppgc/internal/logging.h" 12 | #include "cppgc/platform.h" 13 | #include "v8config.h" // NOLINT(build/include_directory) 14 | 15 | namespace cppgc { 16 | namespace internal { 17 | 18 | class HeapBase; 19 | 20 | #if defined(CPPGC_YOUNG_GENERATION) 21 | 22 | // AgeTable contains entries that correspond to 4KB memory regions. Each entry 23 | // can be in one of three states: kOld, kYoung or kUnknown. 24 | class AgeTable final { 25 | static constexpr size_t kGranularityBits = 12; // 4KiB per byte. 26 | 27 | public: 28 | enum class Age : uint8_t { kOld, kYoung, kUnknown }; 29 | 30 | static constexpr size_t kEntrySizeInBytes = 1 << kGranularityBits; 31 | 32 | Age& operator[](uintptr_t offset) { return table_[entry(offset)]; } 33 | Age operator[](uintptr_t offset) const { return table_[entry(offset)]; } 34 | 35 | void Reset(PageAllocator* allocator); 36 | 37 | private: 38 | static constexpr size_t kAgeTableSize = 39 | api_constants::kCagedHeapReservationSize >> kGranularityBits; 40 | 41 | size_t entry(uintptr_t offset) const { 42 | const size_t entry = offset >> kGranularityBits; 43 | CPPGC_DCHECK(table_.size() > entry); 44 | return entry; 45 | } 46 | 47 | std::array table_; 48 | }; 49 | 50 | static_assert(sizeof(AgeTable) == 1 * api_constants::kMB, 51 | "Size of AgeTable is 1MB"); 52 | 53 | #endif // CPPGC_YOUNG_GENERATION 54 | 55 | struct CagedHeapLocalData final { 56 | explicit CagedHeapLocalData(HeapBase* heap_base) : heap_base(heap_base) {} 57 | 58 | bool is_incremental_marking_in_progress = false; 59 | HeapBase* heap_base = nullptr; 60 | #if defined(CPPGC_YOUNG_GENERATION) 61 | AgeTable age_table; 62 | #endif 63 | }; 64 | 65 | } // namespace internal 66 | } // namespace cppgc 67 | 68 | #endif // INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_LOCAL_DATA_H_ 69 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/compiler-specific.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_COMPILER_SPECIFIC_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_COMPILER_SPECIFIC_H_ 7 | 8 | namespace cppgc { 9 | 10 | #if defined(__has_attribute) 11 | #define CPPGC_HAS_ATTRIBUTE(FEATURE) __has_attribute(FEATURE) 12 | #else 13 | #define CPPGC_HAS_ATTRIBUTE(FEATURE) 0 14 | #endif 15 | 16 | #if defined(__has_cpp_attribute) 17 | #define CPPGC_HAS_CPP_ATTRIBUTE(FEATURE) __has_cpp_attribute(FEATURE) 18 | #else 19 | #define CPPGC_HAS_CPP_ATTRIBUTE(FEATURE) 0 20 | #endif 21 | 22 | // [[no_unique_address]] comes in C++20 but supported in clang with -std >= 23 | // c++11. 24 | #if CPPGC_HAS_CPP_ATTRIBUTE(no_unique_address) 25 | #define CPPGC_NO_UNIQUE_ADDRESS [[no_unique_address]] 26 | #else 27 | #define CPPGC_NO_UNIQUE_ADDRESS 28 | #endif 29 | 30 | #if CPPGC_HAS_ATTRIBUTE(unused) 31 | #define CPPGC_UNUSED __attribute__((unused)) 32 | #else 33 | #define CPPGC_UNUSED 34 | #endif 35 | 36 | } // namespace cppgc 37 | 38 | #endif // INCLUDE_CPPGC_INTERNAL_COMPILER_SPECIFIC_H_ 39 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/finalizer-trait.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/type-traits.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | using FinalizationCallback = void (*)(void*); 16 | 17 | template 18 | struct HasFinalizeGarbageCollectedObject : std::false_type {}; 19 | 20 | template 21 | struct HasFinalizeGarbageCollectedObject< 22 | T, void_t().FinalizeGarbageCollectedObject())>> 23 | : std::true_type {}; 24 | 25 | // The FinalizerTraitImpl specifies how to finalize objects. 26 | template 27 | struct FinalizerTraitImpl; 28 | 29 | template 30 | struct FinalizerTraitImpl { 31 | private: 32 | // Dispatch to custom FinalizeGarbageCollectedObject(). 33 | struct Custom { 34 | static void Call(void* obj) { 35 | static_cast(obj)->FinalizeGarbageCollectedObject(); 36 | } 37 | }; 38 | 39 | // Dispatch to regular destructor. 40 | struct Destructor { 41 | static void Call(void* obj) { static_cast(obj)->~T(); } 42 | }; 43 | 44 | using FinalizeImpl = 45 | std::conditional_t::value, Custom, 46 | Destructor>; 47 | 48 | public: 49 | static void Finalize(void* obj) { 50 | static_assert(sizeof(T), "T must be fully defined"); 51 | FinalizeImpl::Call(obj); 52 | } 53 | }; 54 | 55 | template 56 | struct FinalizerTraitImpl { 57 | static void Finalize(void* obj) { 58 | static_assert(sizeof(T), "T must be fully defined"); 59 | } 60 | }; 61 | 62 | // The FinalizerTrait is used to determine if a type requires finalization and 63 | // what finalization means. 64 | template 65 | struct FinalizerTrait { 66 | private: 67 | // Object has a finalizer if it has 68 | // - a custom FinalizeGarbageCollectedObject method, or 69 | // - a destructor. 70 | static constexpr bool kNonTrivialFinalizer = 71 | internal::HasFinalizeGarbageCollectedObject::value || 72 | !std::is_trivially_destructible::type>::value; 73 | 74 | static void Finalize(void* obj) { 75 | internal::FinalizerTraitImpl::Finalize(obj); 76 | } 77 | 78 | public: 79 | // The callback used to finalize an object of type T. 80 | static constexpr FinalizationCallback kCallback = 81 | kNonTrivialFinalizer ? Finalize : nullptr; 82 | }; 83 | 84 | template 85 | constexpr FinalizationCallback FinalizerTrait::kCallback; 86 | 87 | } // namespace internal 88 | } // namespace cppgc 89 | 90 | #endif // INCLUDE_CPPGC_INTERNAL_FINALIZER_TRAIT_H_ 91 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/gc-info.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_GC_INFO_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_GC_INFO_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "cppgc/internal/finalizer-trait.h" 12 | #include "cppgc/internal/name-trait.h" 13 | #include "cppgc/trace-trait.h" 14 | #include "v8config.h" // NOLINT(build/include_directory) 15 | 16 | namespace cppgc { 17 | namespace internal { 18 | 19 | using GCInfoIndex = uint16_t; 20 | 21 | // Acquires a new GC info object and returns the index. In addition, also 22 | // updates `registered_index` atomically. 23 | V8_EXPORT GCInfoIndex 24 | EnsureGCInfoIndex(std::atomic& registered_index, 25 | FinalizationCallback, TraceCallback, NameCallback, bool); 26 | 27 | // Fold types based on finalizer behavior. Note that finalizer characteristics 28 | // align with trace behavior, i.e., destructors are virtual when trace methods 29 | // are and vice versa. 30 | template 31 | struct GCInfoFolding { 32 | static constexpr bool kHasVirtualDestructorAtBase = 33 | std::has_virtual_destructor::value; 34 | static constexpr bool kBothTypesAreTriviallyDestructible = 35 | std::is_trivially_destructible::value && 36 | std::is_trivially_destructible::value; 37 | static constexpr bool kHasCustomFinalizerDispatchAtBase = 38 | internal::HasFinalizeGarbageCollectedObject< 39 | ParentMostGarbageCollectedType>::value; 40 | #ifdef CPPGC_SUPPORTS_OBJECT_NAMES 41 | static constexpr bool kWantsDetailedObjectNames = true; 42 | #else // !CPPGC_SUPPORTS_OBJECT_NAMES 43 | static constexpr bool kWantsDetailedObjectNames = false; 44 | #endif // !CPPGC_SUPPORTS_OBJECT_NAMES 45 | 46 | // Folding would regresses name resolution when deriving names from C++ 47 | // class names as it would just folds a name to the base class name. 48 | using ResultType = std::conditional_t<(kHasVirtualDestructorAtBase || 49 | kBothTypesAreTriviallyDestructible || 50 | kHasCustomFinalizerDispatchAtBase) && 51 | !kWantsDetailedObjectNames, 52 | ParentMostGarbageCollectedType, T>; 53 | }; 54 | 55 | // Trait determines how the garbage collector treats objects wrt. to traversing, 56 | // finalization, and naming. 57 | template 58 | struct GCInfoTrait final { 59 | static GCInfoIndex Index() { 60 | static_assert(sizeof(T), "T must be fully defined"); 61 | static std::atomic 62 | registered_index; // Uses zero initialization. 63 | const GCInfoIndex index = registered_index.load(std::memory_order_acquire); 64 | return index ? index 65 | : EnsureGCInfoIndex( 66 | registered_index, FinalizerTrait::kCallback, 67 | TraceTrait::Trace, NameTrait::GetName, 68 | std::is_polymorphic::value); 69 | } 70 | }; 71 | 72 | } // namespace internal 73 | } // namespace cppgc 74 | 75 | #endif // INCLUDE_CPPGC_INTERNAL_GC_INFO_H_ 76 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/logging.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_LOGGING_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_LOGGING_H_ 7 | 8 | #include "cppgc/source-location.h" 9 | #include "v8config.h" // NOLINT(build/include_directory) 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | void V8_EXPORT DCheckImpl(const char*, 15 | const SourceLocation& = SourceLocation::Current()); 16 | [[noreturn]] void V8_EXPORT 17 | FatalImpl(const char*, const SourceLocation& = SourceLocation::Current()); 18 | 19 | // Used to ignore -Wunused-variable. 20 | template 21 | struct EatParams {}; 22 | 23 | #if DEBUG 24 | #define CPPGC_DCHECK_MSG(condition, message) \ 25 | do { \ 26 | if (V8_UNLIKELY(!(condition))) { \ 27 | ::cppgc::internal::DCheckImpl(message); \ 28 | } \ 29 | } while (false) 30 | #else 31 | #define CPPGC_DCHECK_MSG(condition, message) \ 32 | (static_cast(::cppgc::internal::EatParams(condition), message)>{})) 34 | #endif 35 | 36 | #define CPPGC_DCHECK(condition) CPPGC_DCHECK_MSG(condition, #condition) 37 | 38 | #define CPPGC_CHECK_MSG(condition, message) \ 39 | do { \ 40 | if (V8_UNLIKELY(!(condition))) { \ 41 | ::cppgc::internal::FatalImpl(message); \ 42 | } \ 43 | } while (false) 44 | 45 | #define CPPGC_CHECK(condition) CPPGC_CHECK_MSG(condition, #condition) 46 | 47 | } // namespace internal 48 | } // namespace cppgc 49 | 50 | #endif // INCLUDE_CPPGC_INTERNAL_LOGGING_H_ 51 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/name-trait.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/name-provider.h" 11 | #include "v8config.h" // NOLINT(build/include_directory) 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | #if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__) 17 | #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 1 18 | 19 | // Provides constexpr c-string storage for a name of fixed |Size| characters. 20 | // Automatically appends terminating 0 byte. 21 | template 22 | struct NameBuffer { 23 | char name[Size + 1]{}; 24 | 25 | static constexpr NameBuffer FromCString(const char* str) { 26 | NameBuffer result; 27 | for (size_t i = 0; i < Size; ++i) result.name[i] = str[i]; 28 | result.name[Size] = 0; 29 | return result; 30 | } 31 | }; 32 | 33 | template 34 | const char* GetTypename() { 35 | static constexpr char kSelfPrefix[] = 36 | "const char *cppgc::internal::GetTypename() [T ="; 37 | static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix, 38 | sizeof(kSelfPrefix) - 1) == 0, 39 | "The prefix must match"); 40 | static constexpr const char* kTypenameStart = 41 | __PRETTY_FUNCTION__ + sizeof(kSelfPrefix); 42 | static constexpr size_t kTypenameSize = 43 | __builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1; 44 | // NameBuffer is an indirection that is needed to make sure that only a 45 | // substring of __PRETTY_FUNCTION__ gets materialized in the binary. 46 | static constexpr auto buffer = 47 | NameBuffer::FromCString(kTypenameStart); 48 | return buffer.name; 49 | } 50 | 51 | #else 52 | #define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 0 53 | #endif 54 | 55 | struct HeapObjectName { 56 | const char* value; 57 | bool name_was_hidden; 58 | }; 59 | 60 | class V8_EXPORT NameTraitBase { 61 | protected: 62 | static HeapObjectName GetNameFromTypeSignature(const char*); 63 | }; 64 | 65 | // Trait that specifies how the garbage collector retrieves the name for a 66 | // given object. 67 | template 68 | class NameTrait final : public NameTraitBase { 69 | public: 70 | static HeapObjectName GetName(const void* obj) { 71 | return GetNameFor(static_cast(obj)); 72 | } 73 | 74 | private: 75 | static HeapObjectName GetNameFor(const NameProvider* name_provider) { 76 | return {name_provider->GetName(), false}; 77 | } 78 | 79 | static HeapObjectName GetNameFor(...) { 80 | #if CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 81 | return {GetTypename(), false}; 82 | #elif CPPGC_SUPPORTS_OBJECT_NAMES 83 | 84 | #if defined(V8_CC_GNU) 85 | #define PRETTY_FUNCTION_VALUE __PRETTY_FUNCTION__ 86 | #elif defined(V8_CC_MSVC) 87 | #define PRETTY_FUNCTION_VALUE __FUNCSIG__ 88 | #else 89 | #define PRETTY_FUNCTION_VALUE nullptr 90 | #endif 91 | 92 | static const HeapObjectName leaky_name = 93 | GetNameFromTypeSignature(PRETTY_FUNCTION_VALUE); 94 | return leaky_name; 95 | 96 | #undef PRETTY_FUNCTION_VALUE 97 | 98 | #else // !CPPGC_SUPPORTS_OBJECT_NAMES 99 | return {NameProvider::kHiddenName, true}; 100 | #endif // !CPPGC_SUPPORTS_OBJECT_NAMES 101 | } 102 | }; 103 | 104 | using NameCallback = HeapObjectName (*)(const void*); 105 | 106 | } // namespace internal 107 | } // namespace cppgc 108 | 109 | #undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME 110 | 111 | #endif // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_ 112 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/persistent-node.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "cppgc/internal/logging.h" 13 | #include "cppgc/trace-trait.h" 14 | #include "v8config.h" // NOLINT(build/include_directory) 15 | 16 | namespace cppgc { 17 | 18 | class Visitor; 19 | 20 | namespace internal { 21 | 22 | class CrossThreadPersistentRegion; 23 | 24 | // PersistentNode represents a variant of two states: 25 | // 1) traceable node with a back pointer to the Persistent object; 26 | // 2) freelist entry. 27 | class PersistentNode final { 28 | public: 29 | PersistentNode() = default; 30 | 31 | PersistentNode(const PersistentNode&) = delete; 32 | PersistentNode& operator=(const PersistentNode&) = delete; 33 | 34 | void InitializeAsUsedNode(void* owner, TraceCallback trace) { 35 | CPPGC_DCHECK(trace); 36 | owner_ = owner; 37 | trace_ = trace; 38 | } 39 | 40 | void InitializeAsFreeNode(PersistentNode* next) { 41 | next_ = next; 42 | trace_ = nullptr; 43 | } 44 | 45 | void UpdateOwner(void* owner) { 46 | CPPGC_DCHECK(IsUsed()); 47 | owner_ = owner; 48 | } 49 | 50 | PersistentNode* FreeListNext() const { 51 | CPPGC_DCHECK(!IsUsed()); 52 | return next_; 53 | } 54 | 55 | void Trace(Visitor* visitor) const { 56 | CPPGC_DCHECK(IsUsed()); 57 | trace_(visitor, owner_); 58 | } 59 | 60 | bool IsUsed() const { return trace_; } 61 | 62 | void* owner() const { 63 | CPPGC_DCHECK(IsUsed()); 64 | return owner_; 65 | } 66 | 67 | private: 68 | // PersistentNode acts as a designated union: 69 | // If trace_ != nullptr, owner_ points to the corresponding Persistent handle. 70 | // Otherwise, next_ points to the next freed PersistentNode. 71 | union { 72 | void* owner_ = nullptr; 73 | PersistentNode* next_; 74 | }; 75 | TraceCallback trace_ = nullptr; 76 | }; 77 | 78 | class V8_EXPORT PersistentRegion final { 79 | using PersistentNodeSlots = std::array; 80 | 81 | public: 82 | PersistentRegion() = default; 83 | // Clears Persistent fields to avoid stale pointers after heap teardown. 84 | ~PersistentRegion(); 85 | 86 | PersistentRegion(const PersistentRegion&) = delete; 87 | PersistentRegion& operator=(const PersistentRegion&) = delete; 88 | 89 | PersistentNode* AllocateNode(void* owner, TraceCallback trace) { 90 | if (!free_list_head_) { 91 | EnsureNodeSlots(); 92 | } 93 | PersistentNode* node = free_list_head_; 94 | free_list_head_ = free_list_head_->FreeListNext(); 95 | CPPGC_DCHECK(!node->IsUsed()); 96 | node->InitializeAsUsedNode(owner, trace); 97 | nodes_in_use_++; 98 | return node; 99 | } 100 | 101 | void FreeNode(PersistentNode* node) { 102 | CPPGC_DCHECK(node); 103 | CPPGC_DCHECK(node->IsUsed()); 104 | node->InitializeAsFreeNode(free_list_head_); 105 | free_list_head_ = node; 106 | CPPGC_DCHECK(nodes_in_use_ > 0); 107 | nodes_in_use_--; 108 | } 109 | 110 | void Trace(Visitor*); 111 | 112 | size_t NodesInUse() const; 113 | 114 | void ClearAllUsedNodes(); 115 | 116 | private: 117 | void EnsureNodeSlots(); 118 | 119 | std::vector> nodes_; 120 | PersistentNode* free_list_head_ = nullptr; 121 | size_t nodes_in_use_ = 0; 122 | 123 | friend class CrossThreadPersistentRegion; 124 | }; 125 | 126 | // CrossThreadPersistent uses PersistentRegion but protects it using this lock 127 | // when needed. 128 | class V8_EXPORT PersistentRegionLock final { 129 | public: 130 | PersistentRegionLock(); 131 | ~PersistentRegionLock(); 132 | 133 | static void AssertLocked(); 134 | }; 135 | 136 | // Variant of PersistentRegion that checks whether the PersistentRegionLock is 137 | // locked. 138 | class V8_EXPORT CrossThreadPersistentRegion final { 139 | public: 140 | CrossThreadPersistentRegion() = default; 141 | // Clears Persistent fields to avoid stale pointers after heap teardown. 142 | ~CrossThreadPersistentRegion(); 143 | 144 | CrossThreadPersistentRegion(const CrossThreadPersistentRegion&) = delete; 145 | CrossThreadPersistentRegion& operator=(const CrossThreadPersistentRegion&) = 146 | delete; 147 | 148 | V8_INLINE PersistentNode* AllocateNode(void* owner, TraceCallback trace) { 149 | PersistentRegionLock::AssertLocked(); 150 | return persistent_region_.AllocateNode(owner, trace); 151 | } 152 | 153 | V8_INLINE void FreeNode(PersistentNode* node) { 154 | PersistentRegionLock::AssertLocked(); 155 | persistent_region_.FreeNode(node); 156 | } 157 | 158 | void Trace(Visitor*); 159 | 160 | size_t NodesInUse() const; 161 | 162 | void ClearAllUsedNodes(); 163 | 164 | private: 165 | PersistentRegion persistent_region_; 166 | }; 167 | 168 | } // namespace internal 169 | 170 | } // namespace cppgc 171 | 172 | #endif // INCLUDE_CPPGC_INTERNAL_PERSISTENT_NODE_H_ 173 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/pointer-policies.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "cppgc/internal/write-barrier.h" 12 | #include "cppgc/sentinel-pointer.h" 13 | #include "cppgc/source-location.h" 14 | #include "cppgc/type-traits.h" 15 | #include "v8config.h" // NOLINT(build/include_directory) 16 | 17 | namespace cppgc { 18 | namespace internal { 19 | 20 | class HeapBase; 21 | class PersistentRegion; 22 | class CrossThreadPersistentRegion; 23 | 24 | // Tags to distinguish between strong and weak member types. 25 | class StrongMemberTag; 26 | class WeakMemberTag; 27 | class UntracedMemberTag; 28 | 29 | struct DijkstraWriteBarrierPolicy { 30 | static void InitializingBarrier(const void*, const void*) { 31 | // Since in initializing writes the source object is always white, having no 32 | // barrier doesn't break the tri-color invariant. 33 | } 34 | static void AssigningBarrier(const void* slot, const void* value) { 35 | WriteBarrier::Params params; 36 | switch (WriteBarrier::GetWriteBarrierType(slot, value, params)) { 37 | case WriteBarrier::Type::kGenerational: 38 | WriteBarrier::GenerationalBarrier(params, slot); 39 | break; 40 | case WriteBarrier::Type::kMarking: 41 | WriteBarrier::DijkstraMarkingBarrier(params, value); 42 | break; 43 | case WriteBarrier::Type::kNone: 44 | break; 45 | } 46 | } 47 | }; 48 | 49 | struct NoWriteBarrierPolicy { 50 | static void InitializingBarrier(const void*, const void*) {} 51 | static void AssigningBarrier(const void*, const void*) {} 52 | }; 53 | 54 | class V8_EXPORT EnabledCheckingPolicy { 55 | protected: 56 | template 57 | void CheckPointer(const T* ptr) { 58 | if (!ptr || (kSentinelPointer == ptr)) return; 59 | 60 | CheckPointersImplTrampoline::Call(this, ptr); 61 | } 62 | 63 | private: 64 | void CheckPointerImpl(const void* ptr, bool points_to_payload); 65 | 66 | template > 67 | struct CheckPointersImplTrampoline { 68 | static void Call(EnabledCheckingPolicy* policy, const T* ptr) { 69 | policy->CheckPointerImpl(ptr, false); 70 | } 71 | }; 72 | 73 | template 74 | struct CheckPointersImplTrampoline { 75 | static void Call(EnabledCheckingPolicy* policy, const T* ptr) { 76 | policy->CheckPointerImpl(ptr, IsGarbageCollectedTypeV); 77 | } 78 | }; 79 | 80 | const HeapBase* heap_ = nullptr; 81 | }; 82 | 83 | class DisabledCheckingPolicy { 84 | protected: 85 | void CheckPointer(const void* raw) {} 86 | }; 87 | 88 | #if V8_ENABLE_CHECKS 89 | using DefaultMemberCheckingPolicy = EnabledCheckingPolicy; 90 | using DefaultPersistentCheckingPolicy = EnabledCheckingPolicy; 91 | #else 92 | using DefaultMemberCheckingPolicy = DisabledCheckingPolicy; 93 | using DefaultPersistentCheckingPolicy = DisabledCheckingPolicy; 94 | #endif 95 | 96 | class KeepLocationPolicy { 97 | public: 98 | constexpr const SourceLocation& Location() const { return location_; } 99 | 100 | protected: 101 | constexpr KeepLocationPolicy() = default; 102 | constexpr explicit KeepLocationPolicy(const SourceLocation& location) 103 | : location_(location) {} 104 | 105 | // KeepLocationPolicy must not copy underlying source locations. 106 | KeepLocationPolicy(const KeepLocationPolicy&) = delete; 107 | KeepLocationPolicy& operator=(const KeepLocationPolicy&) = delete; 108 | 109 | // Location of the original moved from object should be preserved. 110 | KeepLocationPolicy(KeepLocationPolicy&&) = default; 111 | KeepLocationPolicy& operator=(KeepLocationPolicy&&) = default; 112 | 113 | private: 114 | SourceLocation location_; 115 | }; 116 | 117 | class IgnoreLocationPolicy { 118 | public: 119 | constexpr SourceLocation Location() const { return {}; } 120 | 121 | protected: 122 | constexpr IgnoreLocationPolicy() = default; 123 | constexpr explicit IgnoreLocationPolicy(const SourceLocation&) {} 124 | }; 125 | 126 | #if CPPGC_SUPPORTS_OBJECT_NAMES 127 | using DefaultLocationPolicy = KeepLocationPolicy; 128 | #else 129 | using DefaultLocationPolicy = IgnoreLocationPolicy; 130 | #endif 131 | 132 | struct StrongPersistentPolicy { 133 | using IsStrongPersistent = std::true_type; 134 | static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object); 135 | }; 136 | 137 | struct WeakPersistentPolicy { 138 | using IsStrongPersistent = std::false_type; 139 | static V8_EXPORT PersistentRegion& GetPersistentRegion(const void* object); 140 | }; 141 | 142 | struct StrongCrossThreadPersistentPolicy { 143 | using IsStrongPersistent = std::true_type; 144 | static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion( 145 | const void* object); 146 | }; 147 | 148 | struct WeakCrossThreadPersistentPolicy { 149 | using IsStrongPersistent = std::false_type; 150 | static V8_EXPORT CrossThreadPersistentRegion& GetPersistentRegion( 151 | const void* object); 152 | }; 153 | 154 | // Forward declarations setting up the default policies. 155 | template 158 | class BasicCrossThreadPersistent; 159 | template 162 | class BasicPersistent; 163 | template 165 | class BasicMember; 166 | 167 | } // namespace internal 168 | 169 | } // namespace cppgc 170 | 171 | #endif // INCLUDE_CPPGC_INTERNAL_POINTER_POLICIES_H_ 172 | -------------------------------------------------------------------------------- /deps/include/cppgc/internal/prefinalizer-handler.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_INTERNAL_PREFINALIZER_HANDLER_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_PREFINALIZER_HANDLER_H_ 7 | 8 | #include "cppgc/heap.h" 9 | #include "cppgc/liveness-broker.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | class V8_EXPORT PreFinalizerRegistrationDispatcher final { 15 | public: 16 | using PreFinalizerCallback = bool (*)(const LivenessBroker&, void*); 17 | struct PreFinalizer { 18 | void* object; 19 | PreFinalizerCallback callback; 20 | 21 | bool operator==(const PreFinalizer& other) const; 22 | }; 23 | 24 | static void RegisterPrefinalizer(PreFinalizer pre_finalizer); 25 | }; 26 | 27 | } // namespace internal 28 | } // namespace cppgc 29 | 30 | #endif // INCLUDE_CPPGC_INTERNAL_PREFINALIZER_HANDLER_H_ 31 | -------------------------------------------------------------------------------- /deps/include/cppgc/liveness-broker.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_LIVENESS_BROKER_H_ 6 | #define INCLUDE_CPPGC_LIVENESS_BROKER_H_ 7 | 8 | #include "cppgc/heap.h" 9 | #include "cppgc/member.h" 10 | #include "cppgc/trace-trait.h" 11 | #include "v8config.h" // NOLINT(build/include_directory) 12 | 13 | namespace cppgc { 14 | 15 | namespace internal { 16 | class LivenessBrokerFactory; 17 | } // namespace internal 18 | 19 | /** 20 | * The broker is passed to weak callbacks to allow (temporarily) querying 21 | * the liveness state of an object. References to non-live objects must be 22 | * cleared when `IsHeapObjectAlive()` returns false. 23 | * 24 | * \code 25 | * class GCedWithCustomWeakCallback final 26 | * : public GarbageCollected { 27 | * public: 28 | * UntracedMember bar; 29 | * 30 | * void CustomWeakCallbackMethod(const LivenessBroker& broker) { 31 | * if (!broker.IsHeapObjectAlive(bar)) 32 | * bar = nullptr; 33 | * } 34 | * 35 | * void Trace(cppgc::Visitor* visitor) const { 36 | * visitor->RegisterWeakCallbackMethod< 37 | * GCedWithCustomWeakCallback, 38 | * &GCedWithCustomWeakCallback::CustomWeakCallbackMethod>(this); 39 | * } 40 | * }; 41 | * \endcode 42 | */ 43 | class V8_EXPORT LivenessBroker final { 44 | public: 45 | template 46 | bool IsHeapObjectAlive(const T* object) const { 47 | return object && 48 | IsHeapObjectAliveImpl( 49 | TraceTrait::GetTraceDescriptor(object).base_object_payload); 50 | } 51 | 52 | template 53 | bool IsHeapObjectAlive(const WeakMember& weak_member) const { 54 | return (weak_member != kSentinelPointer) && 55 | IsHeapObjectAlive(weak_member.Get()); 56 | } 57 | 58 | template 59 | bool IsHeapObjectAlive(const UntracedMember& untraced_member) const { 60 | return (untraced_member != kSentinelPointer) && 61 | IsHeapObjectAlive(untraced_member.Get()); 62 | } 63 | 64 | private: 65 | LivenessBroker() = default; 66 | 67 | bool IsHeapObjectAliveImpl(const void*) const; 68 | 69 | friend class internal::LivenessBrokerFactory; 70 | }; 71 | 72 | } // namespace cppgc 73 | 74 | #endif // INCLUDE_CPPGC_LIVENESS_BROKER_H_ 75 | -------------------------------------------------------------------------------- /deps/include/cppgc/macros.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_MACROS_H_ 6 | #define INCLUDE_CPPGC_MACROS_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/internal/compiler-specific.h" 11 | 12 | namespace cppgc { 13 | 14 | // Use if the object is only stack allocated. 15 | #define CPPGC_STACK_ALLOCATED() \ 16 | public: \ 17 | using IsStackAllocatedTypeMarker CPPGC_UNUSED = int; \ 18 | \ 19 | private: \ 20 | void* operator new(size_t) = delete; \ 21 | void* operator new(size_t, void*) = delete; \ 22 | static_assert(true, "Force semicolon.") 23 | 24 | } // namespace cppgc 25 | 26 | #endif // INCLUDE_CPPGC_MACROS_H_ 27 | -------------------------------------------------------------------------------- /deps/include/cppgc/member.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_MEMBER_H_ 6 | #define INCLUDE_CPPGC_MEMBER_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "cppgc/internal/pointer-policies.h" 13 | #include "cppgc/sentinel-pointer.h" 14 | #include "cppgc/type-traits.h" 15 | #include "v8config.h" // NOLINT(build/include_directory) 16 | 17 | namespace cppgc { 18 | 19 | class Visitor; 20 | 21 | namespace internal { 22 | 23 | // MemberBase always refers to the object as const object and defers to 24 | // BasicMember on casting to the right type as needed. 25 | class MemberBase { 26 | protected: 27 | struct AtomicInitializerTag {}; 28 | 29 | MemberBase() = default; 30 | explicit MemberBase(const void* value) : raw_(value) {} 31 | MemberBase(const void* value, AtomicInitializerTag) { SetRawAtomic(value); } 32 | 33 | const void** GetRawSlot() const { return &raw_; } 34 | const void* GetRaw() const { return raw_; } 35 | void SetRaw(void* value) { raw_ = value; } 36 | 37 | const void* GetRawAtomic() const { 38 | return reinterpret_cast*>(&raw_)->load( 39 | std::memory_order_relaxed); 40 | } 41 | void SetRawAtomic(const void* value) { 42 | reinterpret_cast*>(&raw_)->store( 43 | value, std::memory_order_relaxed); 44 | } 45 | 46 | void ClearFromGC() const { raw_ = nullptr; } 47 | 48 | private: 49 | mutable const void* raw_ = nullptr; 50 | }; 51 | 52 | // The basic class from which all Member classes are 'generated'. 53 | template 55 | class BasicMember final : private MemberBase, private CheckingPolicy { 56 | public: 57 | using PointeeType = T; 58 | 59 | constexpr BasicMember() = default; 60 | constexpr BasicMember(std::nullptr_t) {} // NOLINT 61 | BasicMember(SentinelPointer s) : MemberBase(s) {} // NOLINT 62 | BasicMember(T* raw) : MemberBase(raw) { // NOLINT 63 | InitializingWriteBarrier(); 64 | this->CheckPointer(Get()); 65 | } 66 | BasicMember(T& raw) : BasicMember(&raw) {} // NOLINT 67 | // Atomic ctor. Using the AtomicInitializerTag forces BasicMember to 68 | // initialize using atomic assignments. This is required for preventing 69 | // data races with concurrent marking. 70 | using AtomicInitializerTag = MemberBase::AtomicInitializerTag; 71 | BasicMember(std::nullptr_t, AtomicInitializerTag atomic) 72 | : MemberBase(nullptr, atomic) {} 73 | BasicMember(SentinelPointer s, AtomicInitializerTag atomic) 74 | : MemberBase(s, atomic) {} 75 | BasicMember(T* raw, AtomicInitializerTag atomic) : MemberBase(raw, atomic) { 76 | InitializingWriteBarrier(); 77 | this->CheckPointer(Get()); 78 | } 79 | BasicMember(T& raw, AtomicInitializerTag atomic) 80 | : BasicMember(&raw, atomic) {} 81 | // Copy ctor. 82 | BasicMember(const BasicMember& other) : BasicMember(other.Get()) {} 83 | // Allow heterogeneous construction. 84 | template ::value>> 87 | BasicMember( // NOLINT 88 | const BasicMember& other) 90 | : BasicMember(other.Get()) {} 91 | // Move ctor. 92 | BasicMember(BasicMember&& other) noexcept : BasicMember(other.Get()) { 93 | other.Clear(); 94 | } 95 | // Allow heterogeneous move construction. 96 | template ::value>> 99 | BasicMember(BasicMember&& other) noexcept 101 | : BasicMember(other.Get()) { 102 | other.Clear(); 103 | } 104 | // Construction from Persistent. 105 | template ::value>> 109 | BasicMember(const BasicPersistent& p) 112 | : BasicMember(p.Get()) {} 113 | 114 | // Copy assignment. 115 | BasicMember& operator=(const BasicMember& other) { 116 | return operator=(other.Get()); 117 | } 118 | // Allow heterogeneous copy assignment. 119 | template ::value>> 122 | BasicMember& operator=( 123 | const BasicMember& other) { 125 | return operator=(other.Get()); 126 | } 127 | // Move assignment. 128 | BasicMember& operator=(BasicMember&& other) noexcept { 129 | operator=(other.Get()); 130 | other.Clear(); 131 | return *this; 132 | } 133 | // Heterogeneous move assignment. 134 | template ::value>> 137 | BasicMember& operator=(BasicMember&& other) noexcept { 139 | operator=(other.Get()); 140 | other.Clear(); 141 | return *this; 142 | } 143 | // Assignment from Persistent. 144 | template ::value>> 148 | BasicMember& operator=( 149 | const BasicPersistent& 151 | other) { 152 | return operator=(other.Get()); 153 | } 154 | BasicMember& operator=(T* other) { 155 | SetRawAtomic(other); 156 | AssigningWriteBarrier(); 157 | this->CheckPointer(Get()); 158 | return *this; 159 | } 160 | BasicMember& operator=(std::nullptr_t) { 161 | Clear(); 162 | return *this; 163 | } 164 | BasicMember& operator=(SentinelPointer s) { 165 | SetRawAtomic(s); 166 | return *this; 167 | } 168 | 169 | template 171 | void Swap(BasicMember& other) { 173 | T* tmp = Get(); 174 | *this = other; 175 | other = tmp; 176 | } 177 | 178 | explicit operator bool() const { return Get(); } 179 | operator T*() const { return Get(); } 180 | T* operator->() const { return Get(); } 181 | T& operator*() const { return *Get(); } 182 | 183 | // CFI cast exemption to allow passing SentinelPointer through T* and support 184 | // heterogeneous assignments between different Member and Persistent handles 185 | // based on their actual types. 186 | V8_CLANG_NO_SANITIZE("cfi-unrelated-cast") T* Get() const { 187 | // Executed by the mutator, hence non atomic load. 188 | // 189 | // The const_cast below removes the constness from MemberBase storage. The 190 | // following static_cast re-adds any constness if specified through the 191 | // user-visible template parameter T. 192 | return static_cast(const_cast(MemberBase::GetRaw())); 193 | } 194 | 195 | void Clear() { SetRawAtomic(nullptr); } 196 | 197 | T* Release() { 198 | T* result = Get(); 199 | Clear(); 200 | return result; 201 | } 202 | 203 | const T** GetSlotForTesting() const { 204 | return reinterpret_cast(GetRawSlot()); 205 | } 206 | 207 | private: 208 | const T* GetRawAtomic() const { 209 | return static_cast(MemberBase::GetRawAtomic()); 210 | } 211 | 212 | void InitializingWriteBarrier() const { 213 | WriteBarrierPolicy::InitializingBarrier(GetRawSlot(), GetRaw()); 214 | } 215 | void AssigningWriteBarrier() const { 216 | WriteBarrierPolicy::AssigningBarrier(GetRawSlot(), GetRaw()); 217 | } 218 | 219 | void ClearFromGC() const { MemberBase::ClearFromGC(); } 220 | 221 | friend class cppgc::Visitor; 222 | template 223 | friend struct cppgc::TraceTrait; 224 | }; 225 | 226 | template 229 | bool operator==( 230 | BasicMember member1, 231 | BasicMember 232 | member2) { 233 | return member1.Get() == member2.Get(); 234 | } 235 | 236 | template 239 | bool operator!=( 240 | BasicMember member1, 241 | BasicMember 242 | member2) { 243 | return !(member1 == member2); 244 | } 245 | 246 | template 247 | struct IsWeak< 248 | internal::BasicMember> 249 | : std::true_type {}; 250 | 251 | } // namespace internal 252 | 253 | /** 254 | * Members are used in classes to contain strong pointers to other garbage 255 | * collected objects. All Member fields of a class must be traced in the class' 256 | * trace method. 257 | */ 258 | template 259 | using Member = internal::BasicMember; 261 | 262 | /** 263 | * WeakMember is similar to Member in that it is used to point to other garbage 264 | * collected objects. However instead of creating a strong pointer to the 265 | * object, the WeakMember creates a weak pointer, which does not keep the 266 | * pointee alive. Hence if all pointers to to a heap allocated object are weak 267 | * the object will be garbage collected. At the time of GC the weak pointers 268 | * will automatically be set to null. 269 | */ 270 | template 271 | using WeakMember = internal::BasicMember; 273 | 274 | /** 275 | * UntracedMember is a pointer to an on-heap object that is not traced for some 276 | * reason. Do not use this unless you know what you are doing. Keeping raw 277 | * pointers to on-heap objects is prohibited unless used from stack. Pointee 278 | * must be kept alive through other means. 279 | */ 280 | template 281 | using UntracedMember = internal::BasicMember; 283 | 284 | } // namespace cppgc 285 | 286 | #endif // INCLUDE_CPPGC_MEMBER_H_ 287 | -------------------------------------------------------------------------------- /deps/include/cppgc/name-provider.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_NAME_PROVIDER_H_ 6 | #define INCLUDE_CPPGC_NAME_PROVIDER_H_ 7 | 8 | #include "v8config.h" // NOLINT(build/include_directory) 9 | 10 | namespace cppgc { 11 | 12 | /** 13 | * NameProvider allows for providing a human-readable name for garbage-collected 14 | * objects. 15 | * 16 | * There's two cases of names to distinguish: 17 | * a. Explicitly specified names via using NameProvider. Such names are always 18 | * preserved in the system. 19 | * b. Internal names that Oilpan infers from a C++ type on the class hierarchy 20 | * of the object. This is not necessarily the type of the actually 21 | * instantiated object. 22 | * 23 | * Depending on the build configuration, Oilpan may hide names, i.e., represent 24 | * them with kHiddenName, of case b. to avoid exposing internal details. 25 | */ 26 | class V8_EXPORT NameProvider { 27 | public: 28 | /** 29 | * Name that is used when hiding internals. 30 | */ 31 | static constexpr const char kHiddenName[] = "InternalNode"; 32 | 33 | /** 34 | * Name that is used in case compiler support is missing for composing a name 35 | * from C++ types. 36 | */ 37 | static constexpr const char kNoNameDeducible[] = ""; 38 | 39 | /** 40 | * Indicating whether internal names are hidden or not. 41 | * 42 | * @returns true if C++ names should be hidden and represented by kHiddenName. 43 | */ 44 | static constexpr bool HideInternalNames() { 45 | #if CPPGC_SUPPORTS_OBJECT_NAMES 46 | return false; 47 | #else // !CPPGC_SUPPORTS_OBJECT_NAMES 48 | return true; 49 | #endif // !CPPGC_SUPPORTS_OBJECT_NAMES 50 | } 51 | 52 | virtual ~NameProvider() = default; 53 | 54 | /** 55 | * Specifies a name for the garbage-collected object. Such names will never 56 | * be hidden, as they are explicitly specified by the user of this API. 57 | * 58 | * @returns a human readable name for the object. 59 | */ 60 | virtual const char* GetName() const = 0; 61 | }; 62 | 63 | } // namespace cppgc 64 | 65 | #endif // INCLUDE_CPPGC_NAME_PROVIDER_H_ 66 | -------------------------------------------------------------------------------- /deps/include/cppgc/object-size-trait.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_OBJECT_SIZE_TRAIT_H_ 6 | #define INCLUDE_CPPGC_OBJECT_SIZE_TRAIT_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/type-traits.h" 11 | #include "v8config.h" // NOLINT(build/include_directory) 12 | 13 | namespace cppgc { 14 | 15 | namespace internal { 16 | 17 | struct V8_EXPORT BaseObjectSizeTrait { 18 | protected: 19 | static size_t GetObjectSizeForGarbageCollected(const void*); 20 | static size_t GetObjectSizeForGarbageCollectedMixin(const void*); 21 | }; 22 | 23 | } // namespace internal 24 | 25 | namespace subtle { 26 | 27 | /** 28 | * Trait specifying how to get the size of an object that was allocated using 29 | * `MakeGarbageCollected()`. Also supports querying the size with an inner 30 | * pointer to a mixin. 31 | */ 32 | template > 33 | struct ObjectSizeTrait; 34 | 35 | template 36 | struct ObjectSizeTrait : cppgc::internal::BaseObjectSizeTrait { 37 | static_assert(sizeof(T), "T must be fully defined"); 38 | static_assert(IsGarbageCollectedTypeV, 39 | "T must be of type GarbageCollected or GarbageCollectedMixin"); 40 | 41 | static size_t GetSize(const T& object) { 42 | return GetObjectSizeForGarbageCollected(&object); 43 | } 44 | }; 45 | 46 | template 47 | struct ObjectSizeTrait : cppgc::internal::BaseObjectSizeTrait { 48 | static_assert(sizeof(T), "T must be fully defined"); 49 | 50 | static size_t GetSize(const T& object) { 51 | return GetObjectSizeForGarbageCollectedMixin(&object); 52 | } 53 | }; 54 | 55 | } // namespace subtle 56 | } // namespace cppgc 57 | 58 | #endif // INCLUDE_CPPGC_OBJECT_SIZE_TRAIT_H_ 59 | -------------------------------------------------------------------------------- /deps/include/cppgc/platform.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_PLATFORM_H_ 6 | #define INCLUDE_CPPGC_PLATFORM_H_ 7 | 8 | #include "v8-platform.h" // NOLINT(build/include_directory) 9 | #include "v8config.h" // NOLINT(build/include_directory) 10 | 11 | namespace cppgc { 12 | 13 | // TODO(v8:10346): Create separate includes for concepts that are not 14 | // V8-specific. 15 | using IdleTask = v8::IdleTask; 16 | using JobHandle = v8::JobHandle; 17 | using JobDelegate = v8::JobDelegate; 18 | using JobTask = v8::JobTask; 19 | using PageAllocator = v8::PageAllocator; 20 | using Task = v8::Task; 21 | using TaskPriority = v8::TaskPriority; 22 | using TaskRunner = v8::TaskRunner; 23 | using TracingController = v8::TracingController; 24 | 25 | /** 26 | * Platform interface used by Heap. Contains allocators and executors. 27 | */ 28 | class V8_EXPORT Platform { 29 | public: 30 | virtual ~Platform() = default; 31 | 32 | /** 33 | * Returns the allocator used by cppgc to allocate its heap and various 34 | * support structures. 35 | */ 36 | virtual PageAllocator* GetPageAllocator() = 0; 37 | 38 | /** 39 | * Monotonically increasing time in seconds from an arbitrary fixed point in 40 | * the past. This function is expected to return at least 41 | * millisecond-precision values. For this reason, 42 | * it is recommended that the fixed point be no further in the past than 43 | * the epoch. 44 | **/ 45 | virtual double MonotonicallyIncreasingTime() = 0; 46 | 47 | /** 48 | * Foreground task runner that should be used by a Heap. 49 | */ 50 | virtual std::shared_ptr GetForegroundTaskRunner() { 51 | return nullptr; 52 | } 53 | 54 | /** 55 | * Posts `job_task` to run in parallel. Returns a `JobHandle` associated with 56 | * the `Job`, which can be joined or canceled. 57 | * This avoids degenerate cases: 58 | * - Calling `CallOnWorkerThread()` for each work item, causing significant 59 | * overhead. 60 | * - Fixed number of `CallOnWorkerThread()` calls that split the work and 61 | * might run for a long time. This is problematic when many components post 62 | * "num cores" tasks and all expect to use all the cores. In these cases, 63 | * the scheduler lacks context to be fair to multiple same-priority requests 64 | * and/or ability to request lower priority work to yield when high priority 65 | * work comes in. 66 | * A canonical implementation of `job_task` looks like: 67 | * \code 68 | * class MyJobTask : public JobTask { 69 | * public: 70 | * MyJobTask(...) : worker_queue_(...) {} 71 | * // JobTask implementation. 72 | * void Run(JobDelegate* delegate) override { 73 | * while (!delegate->ShouldYield()) { 74 | * // Smallest unit of work. 75 | * auto work_item = worker_queue_.TakeWorkItem(); // Thread safe. 76 | * if (!work_item) return; 77 | * ProcessWork(work_item); 78 | * } 79 | * } 80 | * 81 | * size_t GetMaxConcurrency() const override { 82 | * return worker_queue_.GetSize(); // Thread safe. 83 | * } 84 | * }; 85 | * 86 | * // ... 87 | * auto handle = PostJob(TaskPriority::kUserVisible, 88 | * std::make_unique(...)); 89 | * handle->Join(); 90 | * \endcode 91 | * 92 | * `PostJob()` and methods of the returned JobHandle/JobDelegate, must never 93 | * be called while holding a lock that could be acquired by `JobTask::Run()` 94 | * or `JobTask::GetMaxConcurrency()` -- that could result in a deadlock. This 95 | * is because (1) `JobTask::GetMaxConcurrency()` may be invoked while holding 96 | * internal lock (A), hence `JobTask::GetMaxConcurrency()` can only use a lock 97 | * (B) if that lock is *never* held while calling back into `JobHandle` from 98 | * any thread (A=>B/B=>A deadlock) and (2) `JobTask::Run()` or 99 | * `JobTask::GetMaxConcurrency()` may be invoked synchronously from 100 | * `JobHandle` (B=>JobHandle::foo=>B deadlock). 101 | * 102 | * A sufficient `PostJob()` implementation that uses the default Job provided 103 | * in libplatform looks like: 104 | * \code 105 | * std::unique_ptr PostJob( 106 | * TaskPriority priority, std::unique_ptr job_task) override { 107 | * return std::make_unique( 108 | * std::make_shared( 109 | * this, std::move(job_task), kNumThreads)); 110 | * } 111 | * \endcode 112 | */ 113 | virtual std::unique_ptr PostJob( 114 | TaskPriority priority, std::unique_ptr job_task) { 115 | return nullptr; 116 | } 117 | 118 | /** 119 | * Returns an instance of a `TracingController`. This must be non-nullptr. The 120 | * default implementation returns an empty `TracingController` that consumes 121 | * trace data without effect. 122 | */ 123 | virtual TracingController* GetTracingController(); 124 | }; 125 | 126 | /** 127 | * Process-global initialization of the garbage collector. Must be called before 128 | * creating a Heap. 129 | * 130 | * Can be called multiple times when paired with `ShutdownProcess()`. 131 | * 132 | * \param page_allocator The allocator used for maintaining meta data. Must not 133 | * change between multiple calls to InitializeProcess. 134 | */ 135 | V8_EXPORT void InitializeProcess(PageAllocator* page_allocator); 136 | 137 | /** 138 | * Must be called after destroying the last used heap. Some process-global 139 | * metadata may not be returned and reused upon a subsequent 140 | * `InitializeProcess()` call. 141 | */ 142 | V8_EXPORT void ShutdownProcess(); 143 | 144 | namespace internal { 145 | 146 | V8_EXPORT void Abort(); 147 | 148 | } // namespace internal 149 | } // namespace cppgc 150 | 151 | #endif // INCLUDE_CPPGC_PLATFORM_H_ 152 | -------------------------------------------------------------------------------- /deps/include/cppgc/prefinalizer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_PREFINALIZER_H_ 6 | #define INCLUDE_CPPGC_PREFINALIZER_H_ 7 | 8 | #include "cppgc/internal/compiler-specific.h" 9 | #include "cppgc/internal/prefinalizer-handler.h" 10 | #include "cppgc/liveness-broker.h" 11 | 12 | namespace cppgc { 13 | 14 | namespace internal { 15 | 16 | template 17 | class PrefinalizerRegistration final { 18 | public: 19 | explicit PrefinalizerRegistration(T* self) { 20 | static_assert(sizeof(&T::InvokePreFinalizer) > 0, 21 | "USING_PRE_FINALIZER(T) must be defined."); 22 | 23 | cppgc::internal::PreFinalizerRegistrationDispatcher::RegisterPrefinalizer( 24 | {self, T::InvokePreFinalizer}); 25 | } 26 | 27 | void* operator new(size_t, void* location) = delete; 28 | void* operator new(size_t) = delete; 29 | }; 30 | 31 | } // namespace internal 32 | 33 | #define CPPGC_USING_PRE_FINALIZER(Class, PreFinalizer) \ 34 | public: \ 35 | static bool InvokePreFinalizer(const cppgc::LivenessBroker& liveness_broker, \ 36 | void* object) { \ 37 | static_assert(cppgc::IsGarbageCollectedOrMixinTypeV, \ 38 | "Only garbage collected objects can have prefinalizers"); \ 39 | Class* self = static_cast(object); \ 40 | if (liveness_broker.IsHeapObjectAlive(self)) return false; \ 41 | self->Class::PreFinalizer(); \ 42 | return true; \ 43 | } \ 44 | \ 45 | private: \ 46 | CPPGC_NO_UNIQUE_ADDRESS cppgc::internal::PrefinalizerRegistration \ 47 | prefinalizer_dummy_{this}; \ 48 | static_assert(true, "Force semicolon.") 49 | 50 | } // namespace cppgc 51 | 52 | #endif // INCLUDE_CPPGC_PREFINALIZER_H_ 53 | -------------------------------------------------------------------------------- /deps/include/cppgc/process-heap-statistics.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_PROCESS_HEAP_STATISTICS_H_ 6 | #define INCLUDE_CPPGC_PROCESS_HEAP_STATISTICS_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "v8config.h" // NOLINT(build/include_directory) 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | class ProcessHeapStatisticsUpdater; 16 | } // namespace internal 17 | 18 | class V8_EXPORT ProcessHeapStatistics final { 19 | public: 20 | static size_t TotalAllocatedObjectSize() { 21 | return total_allocated_object_size_.load(std::memory_order_relaxed); 22 | } 23 | static size_t TotalAllocatedSpace() { 24 | return total_allocated_space_.load(std::memory_order_relaxed); 25 | } 26 | 27 | private: 28 | static std::atomic_size_t total_allocated_space_; 29 | static std::atomic_size_t total_allocated_object_size_; 30 | 31 | friend class internal::ProcessHeapStatisticsUpdater; 32 | }; 33 | 34 | } // namespace cppgc 35 | 36 | #endif // INCLUDE_CPPGC_PROCESS_HEAP_STATISTICS_H_ 37 | -------------------------------------------------------------------------------- /deps/include/cppgc/sentinel-pointer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_SENTINEL_POINTER_H_ 6 | #define INCLUDE_CPPGC_SENTINEL_POINTER_H_ 7 | 8 | #include 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | // Special tag type used to denote some sentinel member. The semantics of the 14 | // sentinel is defined by the embedder. 15 | struct SentinelPointer { 16 | template 17 | operator T*() const { 18 | static constexpr intptr_t kSentinelValue = 1; 19 | return reinterpret_cast(kSentinelValue); 20 | } 21 | // Hidden friends. 22 | friend bool operator==(SentinelPointer, SentinelPointer) { return true; } 23 | friend bool operator!=(SentinelPointer, SentinelPointer) { return false; } 24 | }; 25 | 26 | } // namespace internal 27 | 28 | constexpr internal::SentinelPointer kSentinelPointer; 29 | 30 | } // namespace cppgc 31 | 32 | #endif // INCLUDE_CPPGC_SENTINEL_POINTER_H_ 33 | -------------------------------------------------------------------------------- /deps/include/cppgc/source-location.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_SOURCE_LOCATION_H_ 6 | #define INCLUDE_CPPGC_SOURCE_LOCATION_H_ 7 | 8 | #include 9 | 10 | #include "v8config.h" // NOLINT(build/include_directory) 11 | 12 | #if defined(__has_builtin) 13 | #define CPPGC_SUPPORTS_SOURCE_LOCATION \ 14 | (__has_builtin(__builtin_FUNCTION) && __has_builtin(__builtin_FILE) && \ 15 | __has_builtin(__builtin_LINE)) // NOLINT 16 | #elif defined(V8_CC_GNU) && __GNUC__ >= 7 17 | #define CPPGC_SUPPORTS_SOURCE_LOCATION 1 18 | #elif defined(V8_CC_INTEL) && __ICC >= 1800 19 | #define CPPGC_SUPPORTS_SOURCE_LOCATION 1 20 | #else 21 | #define CPPGC_SUPPORTS_SOURCE_LOCATION 0 22 | #endif 23 | 24 | namespace cppgc { 25 | 26 | /** 27 | * Encapsulates source location information. Mimics C++20's 28 | * `std::source_location`. 29 | */ 30 | class V8_EXPORT SourceLocation final { 31 | public: 32 | /** 33 | * Construct source location information corresponding to the location of the 34 | * call site. 35 | */ 36 | #if CPPGC_SUPPORTS_SOURCE_LOCATION 37 | static constexpr SourceLocation Current( 38 | const char* function = __builtin_FUNCTION(), 39 | const char* file = __builtin_FILE(), size_t line = __builtin_LINE()) { 40 | return SourceLocation(function, file, line); 41 | } 42 | #else 43 | static constexpr SourceLocation Current() { return SourceLocation(); } 44 | #endif // CPPGC_SUPPORTS_SOURCE_LOCATION 45 | 46 | /** 47 | * Constructs unspecified source location information. 48 | */ 49 | constexpr SourceLocation() = default; 50 | 51 | /** 52 | * Returns the name of the function associated with the position represented 53 | * by this object, if any. 54 | * 55 | * \returns the function name as cstring. 56 | */ 57 | constexpr const char* Function() const { return function_; } 58 | 59 | /** 60 | * Returns the name of the current source file represented by this object. 61 | * 62 | * \returns the file name as cstring. 63 | */ 64 | constexpr const char* FileName() const { return file_; } 65 | 66 | /** 67 | * Returns the line number represented by this object. 68 | * 69 | * \returns the line number. 70 | */ 71 | constexpr size_t Line() const { return line_; } 72 | 73 | /** 74 | * Returns a human-readable string representing this object. 75 | * 76 | * \returns a human-readable string representing source location information. 77 | */ 78 | std::string ToString() const; 79 | 80 | private: 81 | constexpr SourceLocation(const char* function, const char* file, size_t line) 82 | : function_(function), file_(file), line_(line) {} 83 | 84 | const char* function_ = nullptr; 85 | const char* file_ = nullptr; 86 | size_t line_ = 0u; 87 | }; 88 | 89 | } // namespace cppgc 90 | 91 | #endif // INCLUDE_CPPGC_SOURCE_LOCATION_H_ 92 | -------------------------------------------------------------------------------- /deps/include/cppgc/testing.h: -------------------------------------------------------------------------------- 1 | // Copyright 2021 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_TESTING_H_ 6 | #define INCLUDE_CPPGC_TESTING_H_ 7 | 8 | #include "cppgc/common.h" 9 | #include "cppgc/macros.h" 10 | #include "v8config.h" // NOLINT(build/include_directory) 11 | 12 | namespace cppgc { 13 | 14 | class HeapHandle; 15 | 16 | /** 17 | * Namespace contains testing helpers. 18 | */ 19 | namespace testing { 20 | 21 | /** 22 | * Overrides the state of the stack with the provided value. Takes precedence 23 | * over other parameters that set the stack state. Must no be nested. 24 | */ 25 | class V8_EXPORT V8_NODISCARD OverrideEmbedderStackStateScope final { 26 | CPPGC_STACK_ALLOCATED(); 27 | 28 | public: 29 | /** 30 | * Constructs a scoped object that automatically enters and leaves the scope. 31 | * 32 | * \param heap_handle The corresponding heap. 33 | */ 34 | explicit OverrideEmbedderStackStateScope(HeapHandle& heap_handle, 35 | EmbedderStackState state); 36 | ~OverrideEmbedderStackStateScope(); 37 | 38 | OverrideEmbedderStackStateScope(const OverrideEmbedderStackStateScope&) = 39 | delete; 40 | OverrideEmbedderStackStateScope& operator=( 41 | const OverrideEmbedderStackStateScope&) = delete; 42 | 43 | private: 44 | HeapHandle& heap_handle_; 45 | }; 46 | 47 | /** 48 | * Testing interface for managed heaps that allows for controlling garbage 49 | * collection timings. Embedders should use this class when testing the 50 | * interaction of their code with incremental/concurrent garbage collection. 51 | */ 52 | class V8_EXPORT StandaloneTestingHeap final { 53 | public: 54 | explicit StandaloneTestingHeap(HeapHandle&); 55 | 56 | /** 57 | * Start an incremental garbage collection. 58 | */ 59 | void StartGarbageCollection(); 60 | 61 | /** 62 | * Perform an incremental step. This will also schedule concurrent steps if 63 | * needed. 64 | * 65 | * \param stack_state The state of the stack during the step. 66 | */ 67 | bool PerformMarkingStep(EmbedderStackState stack_state); 68 | 69 | /** 70 | * Finalize the current garbage collection cycle atomically. 71 | * Assumes that garbage collection is in progress. 72 | * 73 | * \param stack_state The state of the stack for finalizing the garbage 74 | * collection cycle. 75 | */ 76 | void FinalizeGarbageCollection(EmbedderStackState stack_state); 77 | 78 | /** 79 | * Toggle main thread marking on/off. Allows to stress concurrent marking 80 | * (e.g. to better detect data races). 81 | * 82 | * \param should_mark Denotes whether the main thread should contribute to 83 | * marking. Defaults to true. 84 | */ 85 | void ToggleMainThreadMarking(bool should_mark); 86 | 87 | /** 88 | * Force enable compaction for the next garbage collection cycle. 89 | */ 90 | void ForceCompactionForNextGarbageCollection(); 91 | 92 | private: 93 | HeapHandle& heap_handle_; 94 | }; 95 | 96 | } // namespace testing 97 | } // namespace cppgc 98 | 99 | #endif // INCLUDE_CPPGC_TESTING_H_ 100 | -------------------------------------------------------------------------------- /deps/include/cppgc/trace-trait.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_TRACE_TRAIT_H_ 6 | #define INCLUDE_CPPGC_TRACE_TRAIT_H_ 7 | 8 | #include 9 | 10 | #include "cppgc/type-traits.h" 11 | #include "v8config.h" // NOLINT(build/include_directory) 12 | 13 | namespace cppgc { 14 | 15 | class Visitor; 16 | 17 | namespace internal { 18 | 19 | // Implementation of the default TraceTrait handling GarbageCollected and 20 | // GarbageCollectedMixin. 21 | template ::type>> 24 | struct TraceTraitImpl; 25 | 26 | } // namespace internal 27 | 28 | /** 29 | * Callback for invoking tracing on a given object. 30 | * 31 | * \param visitor The visitor to dispatch to. 32 | * \param object The object to invoke tracing on. 33 | */ 34 | using TraceCallback = void (*)(Visitor* visitor, const void* object); 35 | 36 | /** 37 | * Describes how to trace an object, i.e., how to visit all Oilpan-relevant 38 | * fields of an object. 39 | */ 40 | struct TraceDescriptor { 41 | /** 42 | * Adjusted base pointer, i.e., the pointer to the class inheriting directly 43 | * from GarbageCollected, of the object that is being traced. 44 | */ 45 | const void* base_object_payload; 46 | /** 47 | * Callback for tracing the object. 48 | */ 49 | TraceCallback callback; 50 | }; 51 | 52 | namespace internal { 53 | 54 | struct V8_EXPORT TraceTraitFromInnerAddressImpl { 55 | static TraceDescriptor GetTraceDescriptor(const void* address); 56 | }; 57 | 58 | /** 59 | * Trait specifying how the garbage collector processes an object of type T. 60 | * 61 | * Advanced users may override handling by creating a specialization for their 62 | * type. 63 | */ 64 | template 65 | struct TraceTraitBase { 66 | static_assert(internal::IsTraceableV, "T must have a Trace() method"); 67 | 68 | /** 69 | * Accessor for retrieving a TraceDescriptor to process an object of type T. 70 | * 71 | * \param self The object to be processed. 72 | * \returns a TraceDescriptor to process the object. 73 | */ 74 | static TraceDescriptor GetTraceDescriptor(const void* self) { 75 | return internal::TraceTraitImpl::GetTraceDescriptor( 76 | static_cast(self)); 77 | } 78 | 79 | /** 80 | * Function invoking the tracing for an object of type T. 81 | * 82 | * \param visitor The visitor to dispatch to. 83 | * \param self The object to invoke tracing on. 84 | */ 85 | static void Trace(Visitor* visitor, const void* self) { 86 | static_cast(self)->Trace(visitor); 87 | } 88 | }; 89 | 90 | } // namespace internal 91 | 92 | template 93 | struct TraceTrait : public internal::TraceTraitBase {}; 94 | 95 | namespace internal { 96 | 97 | template 98 | struct TraceTraitImpl { 99 | static_assert(IsGarbageCollectedTypeV, 100 | "T must be of type GarbageCollected or GarbageCollectedMixin"); 101 | static TraceDescriptor GetTraceDescriptor(const void* self) { 102 | return {self, TraceTrait::Trace}; 103 | } 104 | }; 105 | 106 | template 107 | struct TraceTraitImpl { 108 | static TraceDescriptor GetTraceDescriptor(const void* self) { 109 | return internal::TraceTraitFromInnerAddressImpl::GetTraceDescriptor(self); 110 | } 111 | }; 112 | 113 | } // namespace internal 114 | } // namespace cppgc 115 | 116 | #endif // INCLUDE_CPPGC_TRACE_TRAIT_H_ 117 | -------------------------------------------------------------------------------- /deps/include/cppgc/type-traits.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_CPPGC_TYPE_TRAITS_H_ 6 | #define INCLUDE_CPPGC_TYPE_TRAITS_H_ 7 | 8 | // This file should stay with minimal dependencies to allow embedder to check 9 | // against Oilpan types without including any other parts. 10 | #include 11 | #include 12 | 13 | namespace cppgc { 14 | 15 | class Visitor; 16 | 17 | namespace internal { 18 | template 20 | class BasicMember; 21 | struct DijkstraWriteBarrierPolicy; 22 | struct NoWriteBarrierPolicy; 23 | class StrongMemberTag; 24 | class UntracedMemberTag; 25 | class WeakMemberTag; 26 | 27 | // Pre-C++17 custom implementation of std::void_t. 28 | template 29 | struct make_void { 30 | typedef void type; 31 | }; 32 | template 33 | using void_t = typename make_void::type; 34 | 35 | // Not supposed to be specialized by the user. 36 | template 37 | struct IsWeak : std::false_type {}; 38 | 39 | // IsTraceMethodConst is used to verify that all Trace methods are marked as 40 | // const. It is equivalent to IsTraceable but for a non-const object. 41 | template 42 | struct IsTraceMethodConst : std::false_type {}; 43 | 44 | template 45 | struct IsTraceMethodConst().Trace( 46 | std::declval()))>> : std::true_type { 47 | }; 48 | 49 | template 50 | struct IsTraceable : std::false_type { 51 | static_assert(sizeof(T), "T must be fully defined"); 52 | }; 53 | 54 | template 55 | struct IsTraceable< 56 | T, void_t().Trace(std::declval()))>> 57 | : std::true_type { 58 | // All Trace methods should be marked as const. If an object of type 59 | // 'T' is traceable then any object of type 'const T' should also 60 | // be traceable. 61 | static_assert(IsTraceMethodConst(), 62 | "Trace methods should be marked as const."); 63 | }; 64 | 65 | template 66 | constexpr bool IsTraceableV = IsTraceable::value; 67 | 68 | template 69 | struct HasGarbageCollectedMixinTypeMarker : std::false_type { 70 | static_assert(sizeof(T), "T must be fully defined"); 71 | }; 72 | 73 | template 74 | struct HasGarbageCollectedMixinTypeMarker< 75 | T, 76 | void_t::IsGarbageCollectedMixinTypeMarker>> 77 | : std::true_type { 78 | static_assert(sizeof(T), "T must be fully defined"); 79 | }; 80 | 81 | template 82 | struct HasGarbageCollectedTypeMarker : std::false_type { 83 | static_assert(sizeof(T), "T must be fully defined"); 84 | }; 85 | 86 | template 87 | struct HasGarbageCollectedTypeMarker< 88 | T, void_t::IsGarbageCollectedTypeMarker>> 89 | : std::true_type { 90 | static_assert(sizeof(T), "T must be fully defined"); 91 | }; 92 | 93 | template ::value, 94 | bool = HasGarbageCollectedMixinTypeMarker::value> 95 | struct IsGarbageCollectedMixinType : std::false_type { 96 | static_assert(sizeof(T), "T must be fully defined"); 97 | }; 98 | 99 | template 100 | struct IsGarbageCollectedMixinType : std::true_type { 101 | static_assert(sizeof(T), "T must be fully defined"); 102 | }; 103 | 104 | template ::value> 105 | struct IsGarbageCollectedType : std::false_type { 106 | static_assert(sizeof(T), "T must be fully defined"); 107 | }; 108 | 109 | template 110 | struct IsGarbageCollectedType : std::true_type { 111 | static_assert(sizeof(T), "T must be fully defined"); 112 | }; 113 | 114 | template 115 | struct IsGarbageCollectedOrMixinType 116 | : std::integral_constant::value || 117 | IsGarbageCollectedMixinType::value> { 118 | static_assert(sizeof(T), "T must be fully defined"); 119 | }; 120 | 121 | template ::value && 122 | HasGarbageCollectedMixinTypeMarker::value)> 123 | struct IsGarbageCollectedWithMixinType : std::false_type { 124 | static_assert(sizeof(T), "T must be fully defined"); 125 | }; 126 | 127 | template 128 | struct IsGarbageCollectedWithMixinType : std::true_type { 129 | static_assert(sizeof(T), "T must be fully defined"); 130 | }; 131 | 132 | template 134 | struct IsSubclassOfBasicMemberTemplate { 135 | private: 136 | template 137 | static std::true_type SubclassCheck( 138 | BasicMember*); 139 | static std::false_type SubclassCheck(...); 140 | 141 | public: 142 | static constexpr bool value = 143 | decltype(SubclassCheck(std::declval()))::value; 144 | }; 145 | 146 | template ::value> 149 | struct IsMemberType : std::false_type {}; 150 | 151 | template 152 | struct IsMemberType : std::true_type {}; 153 | 154 | template ::value> 156 | struct IsWeakMemberType : std::false_type {}; 157 | 158 | template 159 | struct IsWeakMemberType : std::true_type {}; 160 | 161 | template ::value> 163 | struct IsUntracedMemberType : std::false_type {}; 164 | 165 | template 166 | struct IsUntracedMemberType : std::true_type {}; 167 | 168 | template 169 | struct IsComplete { 170 | private: 171 | template 172 | static std::true_type IsSizeOfKnown(U*); 173 | static std::false_type IsSizeOfKnown(...); 174 | 175 | public: 176 | static constexpr bool value = 177 | decltype(IsSizeOfKnown(std::declval()))::value; 178 | }; 179 | 180 | } // namespace internal 181 | 182 | /** 183 | * Value is true for types that inherit from `GarbageCollectedMixin` but not 184 | * `GarbageCollected` (i.e., they are free mixins), and false otherwise. 185 | */ 186 | template 187 | constexpr bool IsGarbageCollectedMixinTypeV = 188 | internal::IsGarbageCollectedMixinType::value; 189 | 190 | /** 191 | * Value is true for types that inherit from `GarbageCollected`, and false 192 | * otherwise. 193 | */ 194 | template 195 | constexpr bool IsGarbageCollectedTypeV = 196 | internal::IsGarbageCollectedType::value; 197 | 198 | /** 199 | * Value is true for types that inherit from either `GarbageCollected` or 200 | * `GarbageCollectedMixin`, and false otherwise. 201 | */ 202 | template 203 | constexpr bool IsGarbageCollectedOrMixinTypeV = 204 | internal::IsGarbageCollectedOrMixinType::value; 205 | 206 | /** 207 | * Value is true for types that inherit from `GarbageCollected` and 208 | * `GarbageCollectedMixin`, and false otherwise. 209 | */ 210 | template 211 | constexpr bool IsGarbageCollectedWithMixinTypeV = 212 | internal::IsGarbageCollectedWithMixinType::value; 213 | 214 | /** 215 | * Value is true for types of type `Member`, and false otherwise. 216 | */ 217 | template 218 | constexpr bool IsMemberTypeV = internal::IsMemberType::value; 219 | 220 | /** 221 | * Value is true for types of type `UntracedMember`, and false otherwise. 222 | */ 223 | template 224 | constexpr bool IsUntracedMemberTypeV = internal::IsUntracedMemberType::value; 225 | 226 | /** 227 | * Value is true for types of type `WeakMember`, and false otherwise. 228 | */ 229 | template 230 | constexpr bool IsWeakMemberTypeV = internal::IsWeakMemberType::value; 231 | 232 | /** 233 | * Value is true for types that are considered weak references, and false 234 | * otherwise. 235 | */ 236 | template 237 | constexpr bool IsWeakV = internal::IsWeak::value; 238 | 239 | /** 240 | * Value is true for types that are complete, and false otherwise. 241 | */ 242 | template 243 | constexpr bool IsCompleteV = internal::IsComplete::value; 244 | 245 | } // namespace cppgc 246 | 247 | #endif // INCLUDE_CPPGC_TYPE_TRAITS_H_ 248 | -------------------------------------------------------------------------------- /deps/include/libplatform/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | "+libplatform/libplatform-export.h", 3 | ] 4 | 5 | specific_include_rules = { 6 | "libplatform\.h": [ 7 | "+libplatform/v8-tracing.h", 8 | ], 9 | } 10 | -------------------------------------------------------------------------------- /deps/include/libplatform/libplatform-export.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ 6 | #define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ 7 | 8 | #if defined(_WIN32) 9 | 10 | #ifdef BUILDING_V8_PLATFORM_SHARED 11 | #define V8_PLATFORM_EXPORT __declspec(dllexport) 12 | #elif USING_V8_PLATFORM_SHARED 13 | #define V8_PLATFORM_EXPORT __declspec(dllimport) 14 | #else 15 | #define V8_PLATFORM_EXPORT 16 | #endif // BUILDING_V8_PLATFORM_SHARED 17 | 18 | #else // defined(_WIN32) 19 | 20 | // Setup for Linux shared library export. 21 | #ifdef BUILDING_V8_PLATFORM_SHARED 22 | #define V8_PLATFORM_EXPORT __attribute__((visibility("default"))) 23 | #else 24 | #define V8_PLATFORM_EXPORT 25 | #endif 26 | 27 | #endif // defined(_WIN32) 28 | 29 | #endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ 30 | -------------------------------------------------------------------------------- /deps/include/libplatform/libplatform.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_LIBPLATFORM_H_ 6 | #define V8_LIBPLATFORM_LIBPLATFORM_H_ 7 | 8 | #include 9 | 10 | #include "libplatform/libplatform-export.h" 11 | #include "libplatform/v8-tracing.h" 12 | #include "v8-platform.h" // NOLINT(build/include_directory) 13 | #include "v8config.h" // NOLINT(build/include_directory) 14 | 15 | namespace v8 { 16 | namespace platform { 17 | 18 | enum class IdleTaskSupport { kDisabled, kEnabled }; 19 | enum class InProcessStackDumping { kDisabled, kEnabled }; 20 | 21 | enum class MessageLoopBehavior : bool { 22 | kDoNotWait = false, 23 | kWaitForWork = true 24 | }; 25 | 26 | /** 27 | * Returns a new instance of the default v8::Platform implementation. 28 | * 29 | * The caller will take ownership of the returned pointer. |thread_pool_size| 30 | * is the number of worker threads to allocate for background jobs. If a value 31 | * of zero is passed, a suitable default based on the current number of 32 | * processors online will be chosen. 33 | * If |idle_task_support| is enabled then the platform will accept idle 34 | * tasks (IdleTasksEnabled will return true) and will rely on the embedder 35 | * calling v8::platform::RunIdleTasks to process the idle tasks. 36 | * If |tracing_controller| is nullptr, the default platform will create a 37 | * v8::platform::TracingController instance and use it. 38 | */ 39 | V8_PLATFORM_EXPORT std::unique_ptr NewDefaultPlatform( 40 | int thread_pool_size = 0, 41 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, 42 | InProcessStackDumping in_process_stack_dumping = 43 | InProcessStackDumping::kDisabled, 44 | std::unique_ptr tracing_controller = {}); 45 | 46 | /** 47 | * The same as NewDefaultPlatform but disables the worker thread pool. 48 | * It must be used with the --single-threaded V8 flag. 49 | */ 50 | V8_PLATFORM_EXPORT std::unique_ptr 51 | NewSingleThreadedDefaultPlatform( 52 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, 53 | InProcessStackDumping in_process_stack_dumping = 54 | InProcessStackDumping::kDisabled, 55 | std::unique_ptr tracing_controller = {}); 56 | 57 | /** 58 | * Returns a new instance of the default v8::JobHandle implementation. 59 | * 60 | * The job will be executed by spawning up to |num_worker_threads| many worker 61 | * threads on the provided |platform| with the given |priority|. 62 | */ 63 | V8_PLATFORM_EXPORT std::unique_ptr NewDefaultJobHandle( 64 | v8::Platform* platform, v8::TaskPriority priority, 65 | std::unique_ptr job_task, size_t num_worker_threads); 66 | 67 | /** 68 | * Pumps the message loop for the given isolate. 69 | * 70 | * The caller has to make sure that this is called from the right thread. 71 | * Returns true if a task was executed, and false otherwise. If the call to 72 | * PumpMessageLoop is nested within another call to PumpMessageLoop, only 73 | * nestable tasks may run. Otherwise, any task may run. Unless requested through 74 | * the |behavior| parameter, this call does not block if no task is pending. The 75 | * |platform| has to be created using |NewDefaultPlatform|. 76 | */ 77 | V8_PLATFORM_EXPORT bool PumpMessageLoop( 78 | v8::Platform* platform, v8::Isolate* isolate, 79 | MessageLoopBehavior behavior = MessageLoopBehavior::kDoNotWait); 80 | 81 | /** 82 | * Runs pending idle tasks for at most |idle_time_in_seconds| seconds. 83 | * 84 | * The caller has to make sure that this is called from the right thread. 85 | * This call does not block if no task is pending. The |platform| has to be 86 | * created using |NewDefaultPlatform|. 87 | */ 88 | V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform, 89 | v8::Isolate* isolate, 90 | double idle_time_in_seconds); 91 | 92 | /** 93 | * Attempts to set the tracing controller for the given platform. 94 | * 95 | * The |platform| has to be created using |NewDefaultPlatform|. 96 | * 97 | */ 98 | V8_DEPRECATE_SOON("Access the DefaultPlatform directly") 99 | V8_PLATFORM_EXPORT void SetTracingController( 100 | v8::Platform* platform, 101 | v8::platform::tracing::TracingController* tracing_controller); 102 | 103 | /** 104 | * Notifies the given platform about the Isolate getting deleted soon. Has to be 105 | * called for all Isolates which are deleted - unless we're shutting down the 106 | * platform. 107 | * 108 | * The |platform| has to be created using |NewDefaultPlatform|. 109 | * 110 | */ 111 | V8_PLATFORM_EXPORT void NotifyIsolateShutdown(v8::Platform* platform, 112 | Isolate* isolate); 113 | 114 | } // namespace platform 115 | } // namespace v8 116 | 117 | #endif // V8_LIBPLATFORM_LIBPLATFORM_H_ 118 | -------------------------------------------------------------------------------- /deps/include/libplatform/v8-tracing.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_V8_TRACING_H_ 6 | #define V8_LIBPLATFORM_V8_TRACING_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "libplatform/libplatform-export.h" 15 | #include "v8-platform.h" // NOLINT(build/include_directory) 16 | 17 | namespace perfetto { 18 | namespace trace_processor { 19 | class TraceProcessorStorage; 20 | } 21 | class TracingSession; 22 | } 23 | 24 | namespace v8 { 25 | 26 | namespace base { 27 | class Mutex; 28 | } // namespace base 29 | 30 | namespace platform { 31 | namespace tracing { 32 | 33 | class TraceEventListener; 34 | 35 | const int kTraceMaxNumArgs = 2; 36 | 37 | class V8_PLATFORM_EXPORT TraceObject { 38 | public: 39 | union ArgValue { 40 | V8_DEPRECATED("use as_uint ? true : false") bool as_bool; 41 | uint64_t as_uint; 42 | int64_t as_int; 43 | double as_double; 44 | const void* as_pointer; 45 | const char* as_string; 46 | }; 47 | 48 | TraceObject() = default; 49 | ~TraceObject(); 50 | void Initialize( 51 | char phase, const uint8_t* category_enabled_flag, const char* name, 52 | const char* scope, uint64_t id, uint64_t bind_id, int num_args, 53 | const char** arg_names, const uint8_t* arg_types, 54 | const uint64_t* arg_values, 55 | std::unique_ptr* arg_convertables, 56 | unsigned int flags, int64_t timestamp, int64_t cpu_timestamp); 57 | void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp); 58 | void InitializeForTesting( 59 | char phase, const uint8_t* category_enabled_flag, const char* name, 60 | const char* scope, uint64_t id, uint64_t bind_id, int num_args, 61 | const char** arg_names, const uint8_t* arg_types, 62 | const uint64_t* arg_values, 63 | std::unique_ptr* arg_convertables, 64 | unsigned int flags, int pid, int tid, int64_t ts, int64_t tts, 65 | uint64_t duration, uint64_t cpu_duration); 66 | 67 | int pid() const { return pid_; } 68 | int tid() const { return tid_; } 69 | char phase() const { return phase_; } 70 | const uint8_t* category_enabled_flag() const { 71 | return category_enabled_flag_; 72 | } 73 | const char* name() const { return name_; } 74 | const char* scope() const { return scope_; } 75 | uint64_t id() const { return id_; } 76 | uint64_t bind_id() const { return bind_id_; } 77 | int num_args() const { return num_args_; } 78 | const char** arg_names() { return arg_names_; } 79 | uint8_t* arg_types() { return arg_types_; } 80 | ArgValue* arg_values() { return arg_values_; } 81 | std::unique_ptr* arg_convertables() { 82 | return arg_convertables_; 83 | } 84 | unsigned int flags() const { return flags_; } 85 | int64_t ts() { return ts_; } 86 | int64_t tts() { return tts_; } 87 | uint64_t duration() { return duration_; } 88 | uint64_t cpu_duration() { return cpu_duration_; } 89 | 90 | private: 91 | int pid_; 92 | int tid_; 93 | char phase_; 94 | const char* name_; 95 | const char* scope_; 96 | const uint8_t* category_enabled_flag_; 97 | uint64_t id_; 98 | uint64_t bind_id_; 99 | int num_args_ = 0; 100 | const char* arg_names_[kTraceMaxNumArgs]; 101 | uint8_t arg_types_[kTraceMaxNumArgs]; 102 | ArgValue arg_values_[kTraceMaxNumArgs]; 103 | std::unique_ptr 104 | arg_convertables_[kTraceMaxNumArgs]; 105 | char* parameter_copy_storage_ = nullptr; 106 | unsigned int flags_; 107 | int64_t ts_; 108 | int64_t tts_; 109 | uint64_t duration_; 110 | uint64_t cpu_duration_; 111 | 112 | // Disallow copy and assign 113 | TraceObject(const TraceObject&) = delete; 114 | void operator=(const TraceObject&) = delete; 115 | }; 116 | 117 | class V8_PLATFORM_EXPORT TraceWriter { 118 | public: 119 | TraceWriter() = default; 120 | virtual ~TraceWriter() = default; 121 | virtual void AppendTraceEvent(TraceObject* trace_event) = 0; 122 | virtual void Flush() = 0; 123 | 124 | static TraceWriter* CreateJSONTraceWriter(std::ostream& stream); 125 | static TraceWriter* CreateJSONTraceWriter(std::ostream& stream, 126 | const std::string& tag); 127 | 128 | static TraceWriter* CreateSystemInstrumentationTraceWriter(); 129 | 130 | private: 131 | // Disallow copy and assign 132 | TraceWriter(const TraceWriter&) = delete; 133 | void operator=(const TraceWriter&) = delete; 134 | }; 135 | 136 | class V8_PLATFORM_EXPORT TraceBufferChunk { 137 | public: 138 | explicit TraceBufferChunk(uint32_t seq); 139 | 140 | void Reset(uint32_t new_seq); 141 | bool IsFull() const { return next_free_ == kChunkSize; } 142 | TraceObject* AddTraceEvent(size_t* event_index); 143 | TraceObject* GetEventAt(size_t index) { return &chunk_[index]; } 144 | 145 | uint32_t seq() const { return seq_; } 146 | size_t size() const { return next_free_; } 147 | 148 | static const size_t kChunkSize = 64; 149 | 150 | private: 151 | size_t next_free_ = 0; 152 | TraceObject chunk_[kChunkSize]; 153 | uint32_t seq_; 154 | 155 | // Disallow copy and assign 156 | TraceBufferChunk(const TraceBufferChunk&) = delete; 157 | void operator=(const TraceBufferChunk&) = delete; 158 | }; 159 | 160 | class V8_PLATFORM_EXPORT TraceBuffer { 161 | public: 162 | TraceBuffer() = default; 163 | virtual ~TraceBuffer() = default; 164 | 165 | virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0; 166 | virtual TraceObject* GetEventByHandle(uint64_t handle) = 0; 167 | virtual bool Flush() = 0; 168 | 169 | static const size_t kRingBufferChunks = 1024; 170 | 171 | static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks, 172 | TraceWriter* trace_writer); 173 | 174 | private: 175 | // Disallow copy and assign 176 | TraceBuffer(const TraceBuffer&) = delete; 177 | void operator=(const TraceBuffer&) = delete; 178 | }; 179 | 180 | // Options determines how the trace buffer stores data. 181 | enum TraceRecordMode { 182 | // Record until the trace buffer is full. 183 | RECORD_UNTIL_FULL, 184 | 185 | // Record until the user ends the trace. The trace buffer is a fixed size 186 | // and we use it as a ring buffer during recording. 187 | RECORD_CONTINUOUSLY, 188 | 189 | // Record until the trace buffer is full, but with a huge buffer size. 190 | RECORD_AS_MUCH_AS_POSSIBLE, 191 | 192 | // Echo to console. Events are discarded. 193 | ECHO_TO_CONSOLE, 194 | }; 195 | 196 | class V8_PLATFORM_EXPORT TraceConfig { 197 | public: 198 | typedef std::vector StringList; 199 | 200 | static TraceConfig* CreateDefaultTraceConfig(); 201 | 202 | TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {} 203 | TraceRecordMode GetTraceRecordMode() const { return record_mode_; } 204 | const StringList& GetEnabledCategories() const { 205 | return included_categories_; 206 | } 207 | bool IsSystraceEnabled() const { return enable_systrace_; } 208 | bool IsArgumentFilterEnabled() const { return enable_argument_filter_; } 209 | 210 | void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; } 211 | void EnableSystrace() { enable_systrace_ = true; } 212 | void EnableArgumentFilter() { enable_argument_filter_ = true; } 213 | 214 | void AddIncludedCategory(const char* included_category); 215 | 216 | bool IsCategoryGroupEnabled(const char* category_group) const; 217 | 218 | private: 219 | TraceRecordMode record_mode_; 220 | bool enable_systrace_ : 1; 221 | bool enable_argument_filter_ : 1; 222 | StringList included_categories_; 223 | 224 | // Disallow copy and assign 225 | TraceConfig(const TraceConfig&) = delete; 226 | void operator=(const TraceConfig&) = delete; 227 | }; 228 | 229 | #if defined(_MSC_VER) 230 | #define V8_PLATFORM_NON_EXPORTED_BASE(code) \ 231 | __pragma(warning(suppress : 4275)) code 232 | #else 233 | #define V8_PLATFORM_NON_EXPORTED_BASE(code) code 234 | #endif // defined(_MSC_VER) 235 | 236 | class V8_PLATFORM_EXPORT TracingController 237 | : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) { 238 | public: 239 | TracingController(); 240 | ~TracingController() override; 241 | 242 | #if defined(V8_USE_PERFETTO) 243 | // Must be called before StartTracing() if V8_USE_PERFETTO is true. Provides 244 | // the output stream for the JSON trace data. 245 | void InitializeForPerfetto(std::ostream* output_stream); 246 | // Provide an optional listener for testing that will receive trace events. 247 | // Must be called before StartTracing(). 248 | void SetTraceEventListenerForTesting(TraceEventListener* listener); 249 | #else // defined(V8_USE_PERFETTO) 250 | // The pointer returned from GetCategoryGroupEnabled() points to a value with 251 | // zero or more of the following bits. Used in this class only. The 252 | // TRACE_EVENT macros should only use the value as a bool. These values must 253 | // be in sync with macro values in TraceEvent.h in Blink. 254 | enum CategoryGroupEnabledFlags { 255 | // Category group enabled for the recording mode. 256 | ENABLED_FOR_RECORDING = 1 << 0, 257 | // Category group enabled by SetEventCallbackEnabled(). 258 | ENABLED_FOR_EVENT_CALLBACK = 1 << 2, 259 | // Category group enabled to export events to ETW. 260 | ENABLED_FOR_ETW_EXPORT = 1 << 3 261 | }; 262 | 263 | // Takes ownership of |trace_buffer|. 264 | void Initialize(TraceBuffer* trace_buffer); 265 | 266 | // v8::TracingController implementation. 267 | const uint8_t* GetCategoryGroupEnabled(const char* category_group) override; 268 | uint64_t AddTraceEvent( 269 | char phase, const uint8_t* category_enabled_flag, const char* name, 270 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, 271 | const char** arg_names, const uint8_t* arg_types, 272 | const uint64_t* arg_values, 273 | std::unique_ptr* arg_convertables, 274 | unsigned int flags) override; 275 | uint64_t AddTraceEventWithTimestamp( 276 | char phase, const uint8_t* category_enabled_flag, const char* name, 277 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, 278 | const char** arg_names, const uint8_t* arg_types, 279 | const uint64_t* arg_values, 280 | std::unique_ptr* arg_convertables, 281 | unsigned int flags, int64_t timestamp) override; 282 | void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, 283 | const char* name, uint64_t handle) override; 284 | 285 | static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag); 286 | #endif // !defined(V8_USE_PERFETTO) 287 | 288 | void AddTraceStateObserver( 289 | v8::TracingController::TraceStateObserver* observer) override; 290 | void RemoveTraceStateObserver( 291 | v8::TracingController::TraceStateObserver* observer) override; 292 | 293 | void StartTracing(TraceConfig* trace_config); 294 | void StopTracing(); 295 | 296 | protected: 297 | #if !defined(V8_USE_PERFETTO) 298 | virtual int64_t CurrentTimestampMicroseconds(); 299 | virtual int64_t CurrentCpuTimestampMicroseconds(); 300 | #endif // !defined(V8_USE_PERFETTO) 301 | 302 | private: 303 | #if !defined(V8_USE_PERFETTO) 304 | void UpdateCategoryGroupEnabledFlag(size_t category_index); 305 | void UpdateCategoryGroupEnabledFlags(); 306 | #endif // !defined(V8_USE_PERFETTO) 307 | 308 | std::unique_ptr mutex_; 309 | std::unique_ptr trace_config_; 310 | std::atomic_bool recording_{false}; 311 | std::unordered_set observers_; 312 | 313 | #if defined(V8_USE_PERFETTO) 314 | std::ostream* output_stream_ = nullptr; 315 | std::unique_ptr 316 | trace_processor_; 317 | TraceEventListener* listener_for_testing_ = nullptr; 318 | std::unique_ptr tracing_session_; 319 | #else // !defined(V8_USE_PERFETTO) 320 | std::unique_ptr trace_buffer_; 321 | #endif // !defined(V8_USE_PERFETTO) 322 | 323 | // Disallow copy and assign 324 | TracingController(const TracingController&) = delete; 325 | void operator=(const TracingController&) = delete; 326 | }; 327 | 328 | #undef V8_PLATFORM_NON_EXPORTED_BASE 329 | 330 | } // namespace tracing 331 | } // namespace platform 332 | } // namespace v8 333 | 334 | #endif // V8_LIBPLATFORM_V8_TRACING_H_ 335 | -------------------------------------------------------------------------------- /deps/include/v8-cppgc.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_V8_CPPGC_H_ 6 | #define INCLUDE_V8_CPPGC_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "cppgc/common.h" 13 | #include "cppgc/custom-space.h" 14 | #include "cppgc/heap-statistics.h" 15 | #include "cppgc/internal/write-barrier.h" 16 | #include "cppgc/visitor.h" 17 | #include "v8-internal.h" // NOLINT(build/include_directory) 18 | #include "v8.h" // NOLINT(build/include_directory) 19 | 20 | namespace cppgc { 21 | class AllocationHandle; 22 | class HeapHandle; 23 | } // namespace cppgc 24 | 25 | namespace v8 { 26 | 27 | namespace internal { 28 | class CppHeap; 29 | } // namespace internal 30 | 31 | class CustomSpaceStatisticsReceiver; 32 | 33 | /** 34 | * Describes how V8 wrapper objects maintain references to garbage-collected C++ 35 | * objects. 36 | */ 37 | struct WrapperDescriptor final { 38 | /** 39 | * The index used on `v8::Ojbect::SetAlignedPointerFromInternalField()` and 40 | * related APIs to add additional data to an object which is used to identify 41 | * JS->C++ references. 42 | */ 43 | using InternalFieldIndex = int; 44 | 45 | /** 46 | * Unknown embedder id. The value is reserved for internal usages and must not 47 | * be used with `CppHeap`. 48 | */ 49 | static constexpr uint16_t kUnknownEmbedderId = UINT16_MAX; 50 | 51 | constexpr WrapperDescriptor(InternalFieldIndex wrappable_type_index, 52 | InternalFieldIndex wrappable_instance_index, 53 | uint16_t embedder_id_for_garbage_collected) 54 | : wrappable_type_index(wrappable_type_index), 55 | wrappable_instance_index(wrappable_instance_index), 56 | embedder_id_for_garbage_collected(embedder_id_for_garbage_collected) {} 57 | 58 | /** 59 | * Index of the wrappable type. 60 | */ 61 | InternalFieldIndex wrappable_type_index; 62 | 63 | /** 64 | * Index of the wrappable instance. 65 | */ 66 | InternalFieldIndex wrappable_instance_index; 67 | 68 | /** 69 | * Embedder id identifying instances of garbage-collected objects. It is 70 | * expected that the first field of the wrappable type is a uint16_t holding 71 | * the id. Only references to instances of wrappables types with an id of 72 | * `embedder_id_for_garbage_collected` will be considered by CppHeap. 73 | */ 74 | uint16_t embedder_id_for_garbage_collected; 75 | }; 76 | 77 | struct V8_EXPORT CppHeapCreateParams { 78 | CppHeapCreateParams(const CppHeapCreateParams&) = delete; 79 | CppHeapCreateParams& operator=(const CppHeapCreateParams&) = delete; 80 | 81 | std::vector> custom_spaces; 82 | WrapperDescriptor wrapper_descriptor; 83 | }; 84 | 85 | /** 86 | * A heap for allocating managed C++ objects. 87 | */ 88 | class V8_EXPORT CppHeap { 89 | public: 90 | static std::unique_ptr Create(v8::Platform* platform, 91 | const CppHeapCreateParams& params); 92 | 93 | virtual ~CppHeap() = default; 94 | 95 | /** 96 | * \returns the opaque handle for allocating objects using 97 | * `MakeGarbageCollected()`. 98 | */ 99 | cppgc::AllocationHandle& GetAllocationHandle(); 100 | 101 | /** 102 | * \returns the opaque heap handle which may be used to refer to this heap in 103 | * other APIs. Valid as long as the underlying `CppHeap` is alive. 104 | */ 105 | cppgc::HeapHandle& GetHeapHandle(); 106 | 107 | /** 108 | * Terminate clears all roots and performs multiple garbage collections to 109 | * reclaim potentially newly created objects in destructors. 110 | * 111 | * After this call, object allocation is prohibited. 112 | */ 113 | void Terminate(); 114 | 115 | /** 116 | * \param detail_level specifies whether should return detailed 117 | * statistics or only brief summary statistics. 118 | * \returns current CppHeap statistics regarding memory consumption 119 | * and utilization. 120 | */ 121 | cppgc::HeapStatistics CollectStatistics( 122 | cppgc::HeapStatistics::DetailLevel detail_level); 123 | 124 | /** 125 | * Collects statistics for the given spaces and reports them to the receiver. 126 | * 127 | * \param custom_spaces a collection of custom space indicies. 128 | * \param receiver an object that gets the results. 129 | */ 130 | void CollectCustomSpaceStatisticsAtLastGC( 131 | std::vector custom_spaces, 132 | std::unique_ptr receiver); 133 | 134 | /** 135 | * Enables a detached mode that allows testing garbage collection using 136 | * `cppgc::testing` APIs. Once used, the heap cannot be attached to an 137 | * `Isolate` anymore. 138 | */ 139 | void EnableDetachedGarbageCollectionsForTesting(); 140 | 141 | /** 142 | * Performs a stop-the-world garbage collection for testing purposes. 143 | * 144 | * \param stack_state The stack state to assume for the garbage collection. 145 | */ 146 | void CollectGarbageForTesting(cppgc::EmbedderStackState stack_state); 147 | 148 | private: 149 | CppHeap() = default; 150 | 151 | friend class internal::CppHeap; 152 | }; 153 | 154 | class JSVisitor : public cppgc::Visitor { 155 | public: 156 | explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {} 157 | 158 | void Trace(const TracedReferenceBase& ref) { 159 | if (ref.IsEmptyThreadSafe()) return; 160 | Visit(ref); 161 | } 162 | 163 | protected: 164 | using cppgc::Visitor::Visit; 165 | 166 | virtual void Visit(const TracedReferenceBase& ref) {} 167 | }; 168 | 169 | /** 170 | * **DO NOT USE: Use the appropriate managed types.** 171 | * 172 | * Consistency helpers that aid in maintaining a consistent internal state of 173 | * the garbage collector. 174 | */ 175 | class V8_EXPORT JSHeapConsistency final { 176 | public: 177 | using WriteBarrierParams = cppgc::internal::WriteBarrier::Params; 178 | using WriteBarrierType = cppgc::internal::WriteBarrier::Type; 179 | 180 | /** 181 | * Gets the required write barrier type for a specific write. 182 | * 183 | * Note: Handling for C++ to JS references. 184 | * 185 | * \param ref The reference being written to. 186 | * \param params Parameters that may be used for actual write barrier calls. 187 | * Only filled if return value indicates that a write barrier is needed. The 188 | * contents of the `params` are an implementation detail. 189 | * \param callback Callback returning the corresponding heap handle. The 190 | * callback is only invoked if the heap cannot otherwise be figured out. The 191 | * callback must not allocate. 192 | * \returns whether a write barrier is needed and which barrier to invoke. 193 | */ 194 | template 195 | static V8_INLINE WriteBarrierType 196 | GetWriteBarrierType(const TracedReferenceBase& ref, 197 | WriteBarrierParams& params, HeapHandleCallback callback) { 198 | if (ref.IsEmpty()) return WriteBarrierType::kNone; 199 | 200 | if (V8_LIKELY(!cppgc::internal::WriteBarrier:: 201 | IsAnyIncrementalOrConcurrentMarking())) { 202 | return cppgc::internal::WriteBarrier::Type::kNone; 203 | } 204 | cppgc::HeapHandle& handle = callback(); 205 | if (!cppgc::subtle::HeapState::IsMarking(handle)) { 206 | return cppgc::internal::WriteBarrier::Type::kNone; 207 | } 208 | params.heap = &handle; 209 | #if V8_ENABLE_CHECKS 210 | params.type = cppgc::internal::WriteBarrier::Type::kMarking; 211 | #endif // !V8_ENABLE_CHECKS 212 | return cppgc::internal::WriteBarrier::Type::kMarking; 213 | } 214 | 215 | /** 216 | * Gets the required write barrier type for a specific write. 217 | * 218 | * Note: Handling for JS to C++ references. 219 | * 220 | * \param wrapper The wrapper that has been written into. 221 | * \param wrapper_index The wrapper index in `wrapper` that has been written 222 | * into. 223 | * \param wrappable The value that was written. 224 | * \param params Parameters that may be used for actual write barrier calls. 225 | * Only filled if return value indicates that a write barrier is needed. The 226 | * contents of the `params` are an implementation detail. 227 | * \param callback Callback returning the corresponding heap handle. The 228 | * callback is only invoked if the heap cannot otherwise be figured out. The 229 | * callback must not allocate. 230 | * \returns whether a write barrier is needed and which barrier to invoke. 231 | */ 232 | template 233 | static V8_INLINE WriteBarrierType GetWriteBarrierType( 234 | v8::Local& wrapper, int wrapper_index, const void* wrappable, 235 | WriteBarrierParams& params, HeapHandleCallback callback) { 236 | #if V8_ENABLE_CHECKS 237 | CheckWrapper(wrapper, wrapper_index, wrappable); 238 | #endif // V8_ENABLE_CHECKS 239 | return cppgc::internal::WriteBarrier:: 240 | GetWriteBarrierTypeForExternallyReferencedObject(wrappable, params, 241 | callback); 242 | } 243 | 244 | /** 245 | * Conservative Dijkstra-style write barrier that processes an object if it 246 | * has not yet been processed. 247 | * 248 | * \param params The parameters retrieved from `GetWriteBarrierType()`. 249 | * \param ref The reference being written to. 250 | */ 251 | static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams& params, 252 | cppgc::HeapHandle& heap_handle, 253 | const TracedReferenceBase& ref) { 254 | cppgc::internal::WriteBarrier::CheckParams(WriteBarrierType::kMarking, 255 | params); 256 | DijkstraMarkingBarrierSlow(heap_handle, ref); 257 | } 258 | 259 | /** 260 | * Conservative Dijkstra-style write barrier that processes an object if it 261 | * has not yet been processed. 262 | * 263 | * \param params The parameters retrieved from `GetWriteBarrierType()`. 264 | * \param object The pointer to the object. May be an interior pointer to a 265 | * an interface of the actual object. 266 | */ 267 | static V8_INLINE void DijkstraMarkingBarrier(const WriteBarrierParams& params, 268 | cppgc::HeapHandle& heap_handle, 269 | const void* object) { 270 | cppgc::internal::WriteBarrier::DijkstraMarkingBarrier(params, object); 271 | } 272 | 273 | /** 274 | * Generational barrier for maintaining consistency when running with multiple 275 | * generations. 276 | * 277 | * \param params The parameters retrieved from `GetWriteBarrierType()`. 278 | * \param ref The reference being written to. 279 | */ 280 | static V8_INLINE void GenerationalBarrier(const WriteBarrierParams& params, 281 | const TracedReferenceBase& ref) {} 282 | 283 | private: 284 | JSHeapConsistency() = delete; 285 | 286 | static void CheckWrapper(v8::Local&, int, const void*); 287 | 288 | static void DijkstraMarkingBarrierSlow(cppgc::HeapHandle&, 289 | const TracedReferenceBase& ref); 290 | }; 291 | 292 | /** 293 | * Provided as input to `CppHeap::CollectCustomSpaceStatisticsAtLastGC()`. 294 | * 295 | * Its method is invoked with the results of the statistic collection. 296 | */ 297 | class CustomSpaceStatisticsReceiver { 298 | public: 299 | virtual ~CustomSpaceStatisticsReceiver() = default; 300 | /** 301 | * Reports the size of a space at the last GC. It is called for each space 302 | * that was requested in `CollectCustomSpaceStatisticsAtLastGC()`. 303 | * 304 | * \param space_index The index of the space. 305 | * \param bytes The total size of live objects in the space at the last GC. 306 | * It is zero if there was no GC yet. 307 | */ 308 | virtual void AllocatedBytes(cppgc::CustomSpaceIndex space_index, 309 | size_t bytes) = 0; 310 | }; 311 | 312 | } // namespace v8 313 | 314 | namespace cppgc { 315 | 316 | template 317 | struct TraceTrait> { 318 | static void Trace(Visitor* visitor, const v8::TracedReference* self) { 319 | static_cast(visitor)->Trace(*self); 320 | } 321 | }; 322 | 323 | } // namespace cppgc 324 | 325 | #endif // INCLUDE_V8_CPPGC_H_ 326 | -------------------------------------------------------------------------------- /deps/include/v8-inspector-protocol.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_V8_INSPECTOR_PROTOCOL_H_ 6 | #define V8_V8_INSPECTOR_PROTOCOL_H_ 7 | 8 | #include "inspector/Debugger.h" // NOLINT(build/include_directory) 9 | #include "inspector/Runtime.h" // NOLINT(build/include_directory) 10 | #include "inspector/Schema.h" // NOLINT(build/include_directory) 11 | #include "v8-inspector.h" // NOLINT(build/include_directory) 12 | 13 | #endif // V8_V8_INSPECTOR_PROTOCOL_H_ 14 | -------------------------------------------------------------------------------- /deps/include/v8-inspector.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_V8_INSPECTOR_H_ 6 | #define V8_V8_INSPECTOR_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include "v8.h" // NOLINT(build/include_directory) 15 | 16 | namespace v8_inspector { 17 | 18 | namespace protocol { 19 | namespace Debugger { 20 | namespace API { 21 | class SearchMatch; 22 | } 23 | } 24 | namespace Runtime { 25 | namespace API { 26 | class RemoteObject; 27 | class StackTrace; 28 | class StackTraceId; 29 | } 30 | } 31 | namespace Schema { 32 | namespace API { 33 | class Domain; 34 | } 35 | } 36 | } // namespace protocol 37 | 38 | class V8_EXPORT StringView { 39 | public: 40 | StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {} 41 | 42 | StringView(const uint8_t* characters, size_t length) 43 | : m_is8Bit(true), m_length(length), m_characters8(characters) {} 44 | 45 | StringView(const uint16_t* characters, size_t length) 46 | : m_is8Bit(false), m_length(length), m_characters16(characters) {} 47 | 48 | bool is8Bit() const { return m_is8Bit; } 49 | size_t length() const { return m_length; } 50 | 51 | // TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used 52 | // here. 53 | const uint8_t* characters8() const { return m_characters8; } 54 | const uint16_t* characters16() const { return m_characters16; } 55 | 56 | private: 57 | bool m_is8Bit; 58 | size_t m_length; 59 | union { 60 | const uint8_t* m_characters8; 61 | const uint16_t* m_characters16; 62 | }; 63 | }; 64 | 65 | class V8_EXPORT StringBuffer { 66 | public: 67 | virtual ~StringBuffer() = default; 68 | virtual StringView string() const = 0; 69 | // This method copies contents. 70 | static std::unique_ptr create(StringView); 71 | }; 72 | 73 | class V8_EXPORT V8ContextInfo { 74 | public: 75 | V8ContextInfo(v8::Local context, int contextGroupId, 76 | StringView humanReadableName) 77 | : context(context), 78 | contextGroupId(contextGroupId), 79 | humanReadableName(humanReadableName), 80 | hasMemoryOnConsole(false) {} 81 | 82 | v8::Local context; 83 | // Each v8::Context is a part of a group. The group id must be non-zero. 84 | int contextGroupId; 85 | StringView humanReadableName; 86 | StringView origin; 87 | StringView auxData; 88 | bool hasMemoryOnConsole; 89 | 90 | static int executionContextId(v8::Local context); 91 | 92 | // Disallow copying and allocating this one. 93 | enum NotNullTagEnum { NotNullLiteral }; 94 | void* operator new(size_t) = delete; 95 | void* operator new(size_t, NotNullTagEnum, void*) = delete; 96 | void* operator new(size_t, void*) = delete; 97 | V8ContextInfo(const V8ContextInfo&) = delete; 98 | V8ContextInfo& operator=(const V8ContextInfo&) = delete; 99 | }; 100 | 101 | class V8_EXPORT V8StackTrace { 102 | public: 103 | virtual StringView firstNonEmptySourceURL() const = 0; 104 | virtual bool isEmpty() const = 0; 105 | virtual StringView topSourceURL() const = 0; 106 | virtual int topLineNumber() const = 0; 107 | virtual int topColumnNumber() const = 0; 108 | virtual int topScriptId() const = 0; 109 | V8_DEPRECATE_SOON("Use V8::StackTrace::topScriptId() instead.") 110 | int topScriptIdAsInteger() const { return topScriptId(); } 111 | virtual StringView topFunctionName() const = 0; 112 | 113 | virtual ~V8StackTrace() = default; 114 | virtual std::unique_ptr 115 | buildInspectorObject() const = 0; 116 | virtual std::unique_ptr 117 | buildInspectorObject(int maxAsyncDepth) const = 0; 118 | virtual std::unique_ptr toString() const = 0; 119 | 120 | // Safe to pass between threads, drops async chain. 121 | virtual std::unique_ptr clone() = 0; 122 | }; 123 | 124 | class V8_EXPORT V8InspectorSession { 125 | public: 126 | virtual ~V8InspectorSession() = default; 127 | 128 | // Cross-context inspectable values (DOM nodes in different worlds, etc.). 129 | class V8_EXPORT Inspectable { 130 | public: 131 | virtual v8::Local get(v8::Local) = 0; 132 | virtual ~Inspectable() = default; 133 | }; 134 | class V8_EXPORT CommandLineAPIScope { 135 | public: 136 | virtual ~CommandLineAPIScope() = default; 137 | }; 138 | virtual void addInspectedObject(std::unique_ptr) = 0; 139 | 140 | // Dispatching protocol messages. 141 | static bool canDispatchMethod(StringView method); 142 | virtual void dispatchProtocolMessage(StringView message) = 0; 143 | virtual std::vector state() = 0; 144 | virtual std::vector> 145 | supportedDomains() = 0; 146 | 147 | virtual std::unique_ptr 148 | initializeCommandLineAPIScope(int executionContextId) = 0; 149 | 150 | // Debugger actions. 151 | virtual void schedulePauseOnNextStatement(StringView breakReason, 152 | StringView breakDetails) = 0; 153 | virtual void cancelPauseOnNextStatement() = 0; 154 | virtual void breakProgram(StringView breakReason, 155 | StringView breakDetails) = 0; 156 | virtual void setSkipAllPauses(bool) = 0; 157 | virtual void resume(bool setTerminateOnResume = false) = 0; 158 | virtual void stepOver() = 0; 159 | virtual std::vector> 160 | searchInTextByLines(StringView text, StringView query, bool caseSensitive, 161 | bool isRegex) = 0; 162 | 163 | // Remote objects. 164 | virtual std::unique_ptr wrapObject( 165 | v8::Local, v8::Local, StringView groupName, 166 | bool generatePreview) = 0; 167 | 168 | virtual bool unwrapObject(std::unique_ptr* error, 169 | StringView objectId, v8::Local*, 170 | v8::Local*, 171 | std::unique_ptr* objectGroup) = 0; 172 | virtual void releaseObjectGroup(StringView) = 0; 173 | virtual void triggerPreciseCoverageDeltaUpdate(StringView occassion) = 0; 174 | }; 175 | 176 | class V8_EXPORT V8InspectorClient { 177 | public: 178 | virtual ~V8InspectorClient() = default; 179 | 180 | virtual void runMessageLoopOnPause(int contextGroupId) {} 181 | virtual void quitMessageLoopOnPause() {} 182 | virtual void runIfWaitingForDebugger(int contextGroupId) {} 183 | 184 | virtual void muteMetrics(int contextGroupId) {} 185 | virtual void unmuteMetrics(int contextGroupId) {} 186 | 187 | virtual void beginUserGesture() {} 188 | virtual void endUserGesture() {} 189 | 190 | virtual std::unique_ptr valueSubtype(v8::Local) { 191 | return nullptr; 192 | } 193 | virtual std::unique_ptr descriptionForValueSubtype( 194 | v8::Local, v8::Local) { 195 | return nullptr; 196 | } 197 | virtual bool formatAccessorsAsProperties(v8::Local) { 198 | return false; 199 | } 200 | virtual bool isInspectableHeapObject(v8::Local) { return true; } 201 | 202 | virtual v8::Local ensureDefaultContextInGroup( 203 | int contextGroupId) { 204 | return v8::Local(); 205 | } 206 | virtual void beginEnsureAllContextsInGroup(int contextGroupId) {} 207 | virtual void endEnsureAllContextsInGroup(int contextGroupId) {} 208 | 209 | virtual void installAdditionalCommandLineAPI(v8::Local, 210 | v8::Local) {} 211 | virtual void consoleAPIMessage(int contextGroupId, 212 | v8::Isolate::MessageErrorLevel level, 213 | const StringView& message, 214 | const StringView& url, unsigned lineNumber, 215 | unsigned columnNumber, V8StackTrace*) {} 216 | virtual v8::MaybeLocal memoryInfo(v8::Isolate*, 217 | v8::Local) { 218 | return v8::MaybeLocal(); 219 | } 220 | 221 | virtual void consoleTime(const StringView& title) {} 222 | virtual void consoleTimeEnd(const StringView& title) {} 223 | virtual void consoleTimeStamp(const StringView& title) {} 224 | virtual void consoleClear(int contextGroupId) {} 225 | virtual double currentTimeMS() { return 0; } 226 | typedef void (*TimerCallback)(void*); 227 | virtual void startRepeatingTimer(double, TimerCallback, void* data) {} 228 | virtual void cancelTimer(void* data) {} 229 | 230 | // TODO(dgozman): this was added to support service worker shadow page. We 231 | // should not connect at all. 232 | virtual bool canExecuteScripts(int contextGroupId) { return true; } 233 | 234 | virtual void maxAsyncCallStackDepthChanged(int depth) {} 235 | 236 | virtual std::unique_ptr resourceNameToUrl( 237 | const StringView& resourceName) { 238 | return nullptr; 239 | } 240 | 241 | // The caller would defer to generating a random 64 bit integer if 242 | // this method returns 0. 243 | virtual int64_t generateUniqueId() { return 0; } 244 | }; 245 | 246 | // These stack trace ids are intended to be passed between debuggers and be 247 | // resolved later. This allows to track cross-debugger calls and step between 248 | // them if a single client connects to multiple debuggers. 249 | struct V8_EXPORT V8StackTraceId { 250 | uintptr_t id; 251 | std::pair debugger_id; 252 | bool should_pause = false; 253 | 254 | V8StackTraceId(); 255 | V8StackTraceId(const V8StackTraceId&) = default; 256 | V8StackTraceId(uintptr_t id, const std::pair debugger_id); 257 | V8StackTraceId(uintptr_t id, const std::pair debugger_id, 258 | bool should_pause); 259 | explicit V8StackTraceId(StringView); 260 | V8StackTraceId& operator=(const V8StackTraceId&) = default; 261 | V8StackTraceId& operator=(V8StackTraceId&&) noexcept = default; 262 | ~V8StackTraceId() = default; 263 | 264 | bool IsInvalid() const; 265 | std::unique_ptr ToString(); 266 | }; 267 | 268 | class V8_EXPORT V8Inspector { 269 | public: 270 | static std::unique_ptr create(v8::Isolate*, V8InspectorClient*); 271 | virtual ~V8Inspector() = default; 272 | 273 | // Contexts instrumentation. 274 | virtual void contextCreated(const V8ContextInfo&) = 0; 275 | virtual void contextDestroyed(v8::Local) = 0; 276 | virtual void resetContextGroup(int contextGroupId) = 0; 277 | virtual v8::MaybeLocal contextById(int contextId) = 0; 278 | 279 | // Various instrumentation. 280 | virtual void idleStarted() = 0; 281 | virtual void idleFinished() = 0; 282 | 283 | // Async stack traces instrumentation. 284 | virtual void asyncTaskScheduled(StringView taskName, void* task, 285 | bool recurring) = 0; 286 | virtual void asyncTaskCanceled(void* task) = 0; 287 | virtual void asyncTaskStarted(void* task) = 0; 288 | virtual void asyncTaskFinished(void* task) = 0; 289 | virtual void allAsyncTasksCanceled() = 0; 290 | 291 | virtual V8StackTraceId storeCurrentStackTrace(StringView description) = 0; 292 | virtual void externalAsyncTaskStarted(const V8StackTraceId& parent) = 0; 293 | virtual void externalAsyncTaskFinished(const V8StackTraceId& parent) = 0; 294 | 295 | // Exceptions instrumentation. 296 | virtual unsigned exceptionThrown(v8::Local, StringView message, 297 | v8::Local exception, 298 | StringView detailedMessage, StringView url, 299 | unsigned lineNumber, unsigned columnNumber, 300 | std::unique_ptr, 301 | int scriptId) = 0; 302 | virtual void exceptionRevoked(v8::Local, unsigned exceptionId, 303 | StringView message) = 0; 304 | 305 | // Connection. 306 | class V8_EXPORT Channel { 307 | public: 308 | virtual ~Channel() = default; 309 | virtual void sendResponse(int callId, 310 | std::unique_ptr message) = 0; 311 | virtual void sendNotification(std::unique_ptr message) = 0; 312 | virtual void flushProtocolNotifications() = 0; 313 | }; 314 | virtual std::unique_ptr connect(int contextGroupId, 315 | Channel*, 316 | StringView state) = 0; 317 | 318 | // API methods. 319 | virtual std::unique_ptr createStackTrace( 320 | v8::Local) = 0; 321 | virtual std::unique_ptr captureStackTrace(bool fullStack) = 0; 322 | 323 | // Performance counters. 324 | class V8_EXPORT Counters : public std::enable_shared_from_this { 325 | public: 326 | explicit Counters(v8::Isolate* isolate); 327 | ~Counters(); 328 | const std::unordered_map& getCountersMap() const { 329 | return m_countersMap; 330 | } 331 | 332 | private: 333 | static int* getCounterPtr(const char* name); 334 | 335 | v8::Isolate* m_isolate; 336 | std::unordered_map m_countersMap; 337 | }; 338 | 339 | virtual std::shared_ptr enableCounters() = 0; 340 | }; 341 | 342 | } // namespace v8_inspector 343 | 344 | #endif // V8_V8_INSPECTOR_H_ 345 | -------------------------------------------------------------------------------- /deps/include/v8-metrics.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_METRICS_H_ 6 | #define V8_METRICS_H_ 7 | 8 | #include "v8-internal.h" // NOLINT(build/include_directory) 9 | #include "v8.h" // NOLINT(build/include_directory) 10 | 11 | namespace v8 { 12 | namespace metrics { 13 | 14 | struct GarbageCollectionPhases { 15 | int64_t compact_wall_clock_duration_in_us = -1; 16 | int64_t mark_wall_clock_duration_in_us = -1; 17 | int64_t sweep_wall_clock_duration_in_us = -1; 18 | int64_t weak_wall_clock_duration_in_us = -1; 19 | }; 20 | 21 | struct GarbageCollectionSizes { 22 | int64_t bytes_before = -1; 23 | int64_t bytes_after = -1; 24 | int64_t bytes_freed = -1; 25 | }; 26 | 27 | struct GarbageCollectionFullCycle { 28 | GarbageCollectionPhases total; 29 | GarbageCollectionPhases total_cpp; 30 | GarbageCollectionPhases main_thread; 31 | GarbageCollectionPhases main_thread_cpp; 32 | GarbageCollectionPhases main_thread_atomic; 33 | GarbageCollectionPhases main_thread_atomic_cpp; 34 | GarbageCollectionPhases main_thread_incremental; 35 | GarbageCollectionPhases main_thread_incremental_cpp; 36 | GarbageCollectionSizes objects; 37 | GarbageCollectionSizes objects_cpp; 38 | GarbageCollectionSizes memory; 39 | GarbageCollectionSizes memory_cpp; 40 | double collection_rate_in_percent; 41 | double collection_rate_cpp_in_percent; 42 | double efficiency_in_bytes_per_us; 43 | double efficiency_cpp_in_bytes_per_us; 44 | double main_thread_efficiency_in_bytes_per_us; 45 | double main_thread_efficiency_cpp_in_bytes_per_us; 46 | }; 47 | 48 | struct GarbageCollectionFullMainThreadIncrementalMark { 49 | int64_t wall_clock_duration_in_us = -1; 50 | int64_t cpp_wall_clock_duration_in_us = -1; 51 | }; 52 | 53 | struct GarbageCollectionFullMainThreadIncrementalSweep { 54 | int64_t wall_clock_duration_in_us = -1; 55 | int64_t cpp_wall_clock_duration_in_us = -1; 56 | }; 57 | 58 | struct GarbageCollectionYoungCycle { 59 | int64_t total_wall_clock_duration_in_us = -1; 60 | int64_t main_thread_wall_clock_duration_in_us = -1; 61 | double collection_rate_in_percent; 62 | double efficiency_in_bytes_per_us; 63 | double main_thread_efficiency_in_bytes_per_us; 64 | }; 65 | 66 | struct WasmModuleDecoded { 67 | bool async = false; 68 | bool streamed = false; 69 | bool success = false; 70 | size_t module_size_in_bytes = 0; 71 | size_t function_count = 0; 72 | int64_t wall_clock_duration_in_us = -1; 73 | }; 74 | 75 | struct WasmModuleCompiled { 76 | bool async = false; 77 | bool streamed = false; 78 | bool cached = false; 79 | bool deserialized = false; 80 | bool lazy = false; 81 | bool success = false; 82 | size_t code_size_in_bytes = 0; 83 | size_t liftoff_bailout_count = 0; 84 | int64_t wall_clock_duration_in_us = -1; 85 | }; 86 | 87 | struct WasmModuleInstantiated { 88 | bool async = false; 89 | bool success = false; 90 | size_t imported_function_count = 0; 91 | int64_t wall_clock_duration_in_us = -1; 92 | }; 93 | 94 | struct WasmModuleTieredUp { 95 | bool lazy = false; 96 | size_t code_size_in_bytes = 0; 97 | int64_t wall_clock_duration_in_us = -1; 98 | }; 99 | 100 | struct WasmModulesPerIsolate { 101 | size_t count = 0; 102 | }; 103 | 104 | #define V8_MAIN_THREAD_METRICS_EVENTS(V) \ 105 | V(GarbageCollectionFullCycle) \ 106 | V(GarbageCollectionFullMainThreadIncrementalMark) \ 107 | V(GarbageCollectionFullMainThreadIncrementalSweep) \ 108 | V(GarbageCollectionYoungCycle) \ 109 | V(WasmModuleDecoded) \ 110 | V(WasmModuleCompiled) \ 111 | V(WasmModuleInstantiated) \ 112 | V(WasmModuleTieredUp) 113 | 114 | #define V8_THREAD_SAFE_METRICS_EVENTS(V) V(WasmModulesPerIsolate) 115 | 116 | /** 117 | * This class serves as a base class for recording event-based metrics in V8. 118 | * There a two kinds of metrics, those which are expected to be thread-safe and 119 | * whose implementation is required to fulfill this requirement and those whose 120 | * implementation does not have that requirement and only needs to be 121 | * executable on the main thread. If such an event is triggered from a 122 | * background thread, it will be delayed and executed by the foreground task 123 | * runner. 124 | * 125 | * The thread-safe events are listed in the V8_THREAD_SAFE_METRICS_EVENTS 126 | * macro above while the main thread event are listed in 127 | * V8_MAIN_THREAD_METRICS_EVENTS above. For the former, a virtual method 128 | * AddMainThreadEvent(const E& event, v8::Context::Token token) will be 129 | * generated and for the latter AddThreadSafeEvent(const E& event). 130 | * 131 | * Thread-safe events are not allowed to access the context and therefore do 132 | * not carry a context ID with them. These IDs can be generated using 133 | * Recorder::GetContextId() and the ID will be valid throughout the lifetime 134 | * of the isolate. It is not guaranteed that the ID will still resolve to 135 | * a valid context using Recorder::GetContext() at the time the metric is 136 | * recorded. In this case, an empty handle will be returned. 137 | * 138 | * The embedder is expected to call v8::Isolate::SetMetricsRecorder() 139 | * providing its implementation and have the virtual methods overwritten 140 | * for the events it cares about. 141 | */ 142 | class V8_EXPORT Recorder { 143 | public: 144 | // A unique identifier for a context in this Isolate. 145 | // It is guaranteed to not be reused throughout the lifetime of the Isolate. 146 | class ContextId { 147 | public: 148 | ContextId() : id_(kEmptyId) {} 149 | 150 | bool IsEmpty() const { return id_ == kEmptyId; } 151 | static const ContextId Empty() { return ContextId{kEmptyId}; } 152 | 153 | bool operator==(const ContextId& other) const { return id_ == other.id_; } 154 | bool operator!=(const ContextId& other) const { return id_ != other.id_; } 155 | 156 | private: 157 | friend class ::v8::Context; 158 | friend class ::v8::internal::Isolate; 159 | 160 | explicit ContextId(uintptr_t id) : id_(id) {} 161 | 162 | static constexpr uintptr_t kEmptyId = 0; 163 | uintptr_t id_; 164 | }; 165 | 166 | virtual ~Recorder() = default; 167 | 168 | #define ADD_MAIN_THREAD_EVENT(E) \ 169 | virtual void AddMainThreadEvent(const E& event, ContextId context_id) {} 170 | V8_MAIN_THREAD_METRICS_EVENTS(ADD_MAIN_THREAD_EVENT) 171 | #undef ADD_MAIN_THREAD_EVENT 172 | 173 | #define ADD_THREAD_SAFE_EVENT(E) \ 174 | virtual void AddThreadSafeEvent(const E& event) {} 175 | V8_THREAD_SAFE_METRICS_EVENTS(ADD_THREAD_SAFE_EVENT) 176 | #undef ADD_THREAD_SAFE_EVENT 177 | 178 | virtual void NotifyIsolateDisposal() {} 179 | 180 | // Return the context with the given id or an empty handle if the context 181 | // was already garbage collected. 182 | static MaybeLocal GetContext(Isolate* isolate, ContextId id); 183 | // Return the unique id corresponding to the given context. 184 | static ContextId GetContextId(Local context); 185 | }; 186 | 187 | /** 188 | * Experimental API intended for the LongTasks UKM (crbug.com/1173527). 189 | * The Reset() method should be called at the start of a potential 190 | * long task. The Get() method returns durations of V8 work that 191 | * happened during the task. 192 | * 193 | * This API is experimental and may be removed/changed in the future. 194 | */ 195 | struct V8_EXPORT LongTaskStats { 196 | /** 197 | * Resets durations of V8 work for the new task. 198 | */ 199 | V8_INLINE static void Reset(Isolate* isolate) { 200 | v8::internal::Internals::IncrementLongTasksStatsCounter(isolate); 201 | } 202 | 203 | /** 204 | * Returns durations of V8 work that happened since the last Reset(). 205 | */ 206 | static LongTaskStats Get(Isolate* isolate); 207 | 208 | int64_t gc_full_atomic_wall_clock_duration_us = 0; 209 | int64_t gc_full_incremental_wall_clock_duration_us = 0; 210 | int64_t gc_young_wall_clock_duration_us = 0; 211 | }; 212 | 213 | } // namespace metrics 214 | } // namespace v8 215 | 216 | #endif // V8_METRICS_H_ 217 | -------------------------------------------------------------------------------- /deps/include/v8-unwinder-state.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDE_V8_UNWINDER_STATE_H_ 6 | #define INCLUDE_V8_UNWINDER_STATE_H_ 7 | 8 | namespace v8 { 9 | 10 | #ifdef V8_TARGET_ARCH_ARM 11 | struct CalleeSavedRegisters { 12 | void* arm_r4; 13 | void* arm_r5; 14 | void* arm_r6; 15 | void* arm_r7; 16 | void* arm_r8; 17 | void* arm_r9; 18 | void* arm_r10; 19 | }; 20 | #elif V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 || \ 21 | V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC || \ 22 | V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_S390 23 | struct CalleeSavedRegisters {}; 24 | #else 25 | #error Target architecture was not detected as supported by v8 26 | #endif 27 | 28 | } // namespace v8 29 | 30 | #endif // INCLUDE_V8_UNWINDER _STATE_H_ 31 | -------------------------------------------------------------------------------- /deps/include/v8-value-serializer-version.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | /** 6 | * Compile-time constants. 7 | * 8 | * This header provides access to information about the value serializer at 9 | * compile time, without declaring or defining any symbols that require linking 10 | * to V8. 11 | */ 12 | 13 | #ifndef INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_ 14 | #define INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_ 15 | 16 | #include 17 | 18 | namespace v8 { 19 | 20 | constexpr uint32_t CurrentValueSerializerFormatVersion() { return 13; } 21 | 22 | } // namespace v8 23 | 24 | #endif // INCLUDE_V8_VALUE_SERIALIZER_VERSION_H_ 25 | -------------------------------------------------------------------------------- /deps/include/v8-version-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_VERSION_STRING_H_ 6 | #define V8_VERSION_STRING_H_ 7 | 8 | #include "v8-version.h" // NOLINT(build/include_directory) 9 | 10 | // This is here rather than v8-version.h to keep that file simple and 11 | // machine-processable. 12 | 13 | #if V8_IS_CANDIDATE_VERSION 14 | #define V8_CANDIDATE_STRING " (candidate)" 15 | #else 16 | #define V8_CANDIDATE_STRING "" 17 | #endif 18 | 19 | #ifndef V8_EMBEDDER_STRING 20 | #define V8_EMBEDDER_STRING "" 21 | #endif 22 | 23 | #define V8_SX(x) #x 24 | #define V8_S(x) V8_SX(x) 25 | 26 | #if V8_PATCH_LEVEL > 0 27 | #define V8_VERSION_STRING \ 28 | V8_S(V8_MAJOR_VERSION) \ 29 | "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \ 30 | V8_PATCH_LEVEL) V8_EMBEDDER_STRING V8_CANDIDATE_STRING 31 | #else 32 | #define V8_VERSION_STRING \ 33 | V8_S(V8_MAJOR_VERSION) \ 34 | "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) \ 35 | V8_EMBEDDER_STRING V8_CANDIDATE_STRING 36 | #endif 37 | 38 | #endif // V8_VERSION_STRING_H_ 39 | -------------------------------------------------------------------------------- /deps/include/v8-version.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_INCLUDE_VERSION_H_ // V8_VERSION_H_ conflicts with src/version.h 6 | #define V8_INCLUDE_VERSION_H_ 7 | 8 | // These macros define the version number for the current version. 9 | // NOTE these macros are used by some of the tool scripts and the build 10 | // system so their names cannot be changed without changing the scripts. 11 | #define V8_MAJOR_VERSION 9 12 | #define V8_MINOR_VERSION 2 13 | #define V8_BUILD_NUMBER 230 14 | #define V8_PATCH_LEVEL 20 15 | 16 | // Use 1 for candidates and 0 otherwise. 17 | // (Boolean macro values are not supported by all preprocessors.) 18 | #define V8_IS_CANDIDATE_VERSION 0 19 | 20 | #endif // V8_INCLUDE_VERSION_H_ 21 | -------------------------------------------------------------------------------- /deps/include/v8-wasm-trap-handler-posix.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_WASM_TRAP_HANDLER_POSIX_H_ 6 | #define V8_WASM_TRAP_HANDLER_POSIX_H_ 7 | 8 | #include 9 | 10 | #include "v8config.h" // NOLINT(build/include_directory) 11 | 12 | namespace v8 { 13 | /** 14 | * This function determines whether a memory access violation has been an 15 | * out-of-bounds memory access in WebAssembly. If so, it will modify the context 16 | * parameter and add a return address where the execution can continue after the 17 | * signal handling, and return true. Otherwise, false will be returned. 18 | * 19 | * The parameters to this function correspond to those passed to a Posix signal 20 | * handler. Use this function only on Linux and Mac. 21 | * 22 | * \param sig_code The signal code, e.g. SIGSEGV. 23 | * \param info A pointer to the siginfo_t struct provided to the signal handler. 24 | * \param context A pointer to a ucontext_t struct provided to the signal 25 | * handler. 26 | */ 27 | V8_EXPORT bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info, 28 | void* context); 29 | 30 | } // namespace v8 31 | #endif // V8_WASM_TRAP_HANDLER_POSIX_H_ 32 | -------------------------------------------------------------------------------- /deps/include/v8-wasm-trap-handler-win.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_WASM_TRAP_HANDLER_WIN_H_ 6 | #define V8_WASM_TRAP_HANDLER_WIN_H_ 7 | 8 | #include 9 | 10 | #include "v8config.h" // NOLINT(build/include_directory) 11 | 12 | namespace v8 { 13 | /** 14 | * This function determines whether a memory access violation has been an 15 | * out-of-bounds memory access in WebAssembly. If so, it will modify the 16 | * exception parameter and add a return address where the execution can continue 17 | * after the exception handling, and return true. Otherwise the return value 18 | * will be false. 19 | * 20 | * The parameter to this function corresponds to the one passed to a Windows 21 | * vectored exception handler. Use this function only on Windows. 22 | * 23 | * \param exception An EXCEPTION_POINTERS* as provided to the exception handler. 24 | */ 25 | V8_EXPORT bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception); 26 | 27 | } // namespace v8 28 | #endif // V8_WASM_TRAP_HANDLER_WIN_H_ 29 | -------------------------------------------------------------------------------- /deps/libv8_monolith.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmadov/v8_inspector_example/8d993d71dc74910da90907fd97b50226496aaafd/deps/libv8_monolith.a -------------------------------------------------------------------------------- /example/code.js: -------------------------------------------------------------------------------- 1 | function main() { 2 | console.log('Hello, ChromeDevTools!'); 3 | console.log("I heard you're an amazing tool! I'm here to play with you!"); 4 | for (var i = 1; i <= 5; ++i) { 5 | console.log(i + " * " + i + " = " + i * i); 6 | } 7 | var a = 7; 8 | var b = 5; 9 | var c = a * b; 10 | console.log(a + " * " + b + " = " + c); 11 | } 12 | var sayHi = function (name) { 13 | console.log("Hi, " + name); 14 | }; 15 | main(); 16 | sayHi('Foo'); 17 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsU0FBUyxJQUFJO0lBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNERBQTRELENBQUMsQ0FBQztJQUUxRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFO1FBQ3pCLE9BQU8sQ0FBQyxHQUFHLENBQUksQ0FBQyxXQUFNLENBQUMsV0FBTSxDQUFDLEdBQUcsQ0FBRyxDQUFDLENBQUM7S0FDekM7SUFFRCxJQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDWixJQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDWixJQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRWhCLE9BQU8sQ0FBQyxHQUFHLENBQUksQ0FBQyxXQUFNLENBQUMsV0FBTSxDQUFHLENBQUMsQ0FBQztBQUN0QyxDQUFDO0FBRUQsSUFBTSxLQUFLLEdBQUcsVUFBQyxJQUFZO0lBQ3ZCLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBTyxJQUFNLENBQUMsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFFRixJQUFJLEVBQUUsQ0FBQztBQUVQLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIG1haW4oKSB7XG4gICAgY29uc29sZS5sb2coJ0hlbGxvLCBDaHJvbWVEZXZUb29scyEnKTtcbiAgICBjb25zb2xlLmxvZyhgSSBoZWFyZCB5b3UncmUgYW4gYW1hemluZyB0b29sISBJJ20gaGVyZSB0byBwbGF5IHdpdGggeW91IWApO1xuXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gNTsgKytpKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke2l9ICogJHtpfSA9ICR7aSAqIGl9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgYSA9IDc7XG4gICAgY29uc3QgYiA9IDU7XG4gICAgY29uc3QgYyA9IGEgKiBiO1xuXG4gICAgY29uc29sZS5sb2coYCR7YX0gKiAke2J9ID0gJHtjfWApO1xufVxuXG5jb25zdCBzYXlIaSA9IChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICBjb25zb2xlLmxvZyhgSGksICR7bmFtZX1gKTtcbn07XG5cbm1haW4oKTtcblxuc2F5SGkoJ0ZvbycpOyJdfQ== -------------------------------------------------------------------------------- /example/code.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"code.js","sourceRoot":"","sources":["code.ts"],"names":[],"mappings":"AAAA,SAAS,IAAI;IACT,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;IAE1E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE;QACzB,OAAO,CAAC,GAAG,CAAI,CAAC,WAAM,CAAC,WAAM,CAAC,GAAG,CAAG,CAAC,CAAC;KACzC;IAED,IAAM,CAAC,GAAG,CAAC,CAAC;IACZ,IAAM,CAAC,GAAG,CAAC,CAAC;IACZ,IAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEhB,OAAO,CAAC,GAAG,CAAI,CAAC,WAAM,CAAC,WAAM,CAAG,CAAC,CAAC;AACtC,CAAC;AAED,IAAI,EAAE,CAAC"} -------------------------------------------------------------------------------- /example/code.ts: -------------------------------------------------------------------------------- 1 | function main() { 2 | console.log('Hello, ChromeDevTools!'); 3 | console.log(`I heard you're an amazing tool! I'm here to play with you!`); 4 | 5 | for (let i = 1; i <= 5; ++i) { 6 | console.log(`${i} * ${i} = ${i * i}`); 7 | } 8 | 9 | const a = 7; 10 | const b = 5; 11 | const c = a * b; 12 | 13 | console.log(`${a} * ${b} = ${c}`); 14 | } 15 | 16 | const sayHi = (name: string) => { 17 | console.log(`Hi, ${name}`); 18 | }; 19 | 20 | main(); 21 | 22 | sayHi('Foo'); 23 | -------------------------------------------------------------------------------- /src/Inspector.cpp: -------------------------------------------------------------------------------- 1 | #include "Inspector.h" 2 | 3 | Inspector::Inspector( 4 | const std::unique_ptr &platform, 5 | const v8::Local &context, 6 | const int webSocketPort) { 7 | context_ = context; 8 | websocket_server_ = std::unique_ptr( 9 | new WebSocketServer( 10 | webSocketPort, 11 | std::bind(&Inspector::onMessage, this, std::placeholders::_1) 12 | ) 13 | ); 14 | inspector_client_ = std::unique_ptr( 15 | new V8InspectorClientImpl( 16 | platform, 17 | context_, 18 | std::bind(&Inspector::sendMessage, this, std::placeholders::_1), 19 | std::bind(&Inspector::waitForFrontendMessage, this) 20 | ) 21 | ); 22 | } 23 | 24 | void Inspector::onMessage(const std::string& message) { 25 | std::cout << "CDT message: " << message << std::endl; 26 | v8_inspector::StringView protocolMessage = convertToStringView(message); 27 | inspector_client_->dispatchProtocolMessage(protocolMessage); 28 | 29 | v8::Local jsonObject = parseJson(context_, message); 30 | if (!jsonObject.IsEmpty()) { 31 | std::string method = getPropertyFromJson(context_->GetIsolate(), jsonObject, "method"); 32 | if (method == "Runtime.runIfWaitingForDebugger") { 33 | inspector_client_->schedulePauseOnNextStatement(convertToStringView("For testing purpose!")); 34 | inspector_client_->waitFrontendMessageOnPause(); 35 | std::for_each(listeners_.begin(), listeners_.end(), [this](V8InspectorListener* listener) { 36 | listener->onConnected(context_); 37 | }); 38 | } 39 | } 40 | } 41 | 42 | void Inspector::sendMessage(const std::string& message) { 43 | std::cout << "Message to frontend: " << message << std::endl; 44 | websocket_server_->sendMessage(message); 45 | } 46 | 47 | void Inspector::startAgent() { 48 | websocket_server_->run(); 49 | } 50 | 51 | int Inspector::waitForFrontendMessage() { 52 | websocket_server_->waitForFrontendMessageOnPause(); 53 | return 1; 54 | } 55 | 56 | void Inspector::addListener(V8InspectorListener* listener) { 57 | listeners_.emplace_back(listener); 58 | } 59 | -------------------------------------------------------------------------------- /src/Inspector.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "websocket_server.h" 6 | #include "v8inspector_client.h" 7 | #include "v8inspector_listener.h" 8 | #include "utils.h" 9 | 10 | #ifndef V8_INSPECTOR_EXAMPLE_INSPECTOR_H 11 | #define V8_INSPECTOR_EXAMPLE_INSPECTOR_H 12 | 13 | 14 | class Inspector { 15 | public: 16 | Inspector(const std::unique_ptr &platform, const v8::Local &context, int webSocketPort); 17 | 18 | void addListener(V8InspectorListener* listener); 19 | void startAgent(); 20 | private: 21 | void onMessage(const std::string& message); 22 | void sendMessage(const std::string& message); 23 | int waitForFrontendMessage(); 24 | 25 | v8::Handle context_; 26 | std::unique_ptr websocket_server_; 27 | std::unique_ptr inspector_client_; 28 | std::vector scripts = {}; 29 | std::list listeners_; 30 | }; 31 | 32 | 33 | #endif //V8_INSPECTOR_EXAMPLE_INSPECTOR_H 34 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "Inspector.h" 5 | #include "v8_inspector_listener_impl.h" 6 | 7 | const static int port = 9005; 8 | std::unique_ptr v8Platform = nullptr; 9 | std::unique_ptr inspector = nullptr; 10 | 11 | int main() 12 | { 13 | v8::V8::InitializeICU(); 14 | v8Platform = v8::platform::NewDefaultPlatform(); 15 | v8::V8::InitializePlatform(v8Platform.get()); 16 | v8::V8::Initialize(); 17 | 18 | v8::Isolate::CreateParams create_params; 19 | create_params.array_buffer_allocator = 20 | v8::ArrayBuffer::Allocator::NewDefaultAllocator(); 21 | v8::Isolate* isolate = v8::Isolate::New(create_params); 22 | { 23 | v8::Isolate::Scope isolate_scope(isolate); 24 | v8::HandleScope scope(isolate); 25 | v8::Handle context = v8::Context::New(isolate); 26 | v8::Context::Scope context_scope(context); 27 | 28 | inspector = std::unique_ptr(new Inspector(v8Platform, context, port)); 29 | 30 | inspector->addListener(new BaseV8InspectorListenerImpl()); 31 | inspector->startAgent(); 32 | 33 | } 34 | 35 | isolate->Dispose(); 36 | v8::V8::Dispose(); 37 | v8::V8::ShutdownPlatform(); 38 | delete create_params.array_buffer_allocator; 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef UTILS_H 7 | #define UTILS_H 8 | 9 | static inline std::string convertToString(v8::Isolate* isolate, const v8_inspector::StringView stringView) { 10 | int length = static_cast(stringView.length()); 11 | v8::Local message = ( 12 | stringView.is8Bit() 13 | ? v8::String::NewFromOneByte(isolate, reinterpret_cast(stringView.characters8()), v8::NewStringType::kNormal, length) 14 | : v8::String::NewFromTwoByte(isolate, reinterpret_cast(stringView.characters16()), v8::NewStringType::kNormal, length) 15 | ).ToLocalChecked(); 16 | v8::String::Utf8Value result(isolate, message); 17 | return *result; 18 | } 19 | 20 | static inline v8_inspector::StringView convertToStringView(const std::string &str) { 21 | auto* stringView = reinterpret_cast(str.c_str()); 22 | return { stringView, str.length() }; 23 | } 24 | 25 | static inline v8::Local parseJson(const v8::Local &context, const std::string &json) { 26 | v8::MaybeLocal value_ = v8::JSON::Parse(context, v8::String::NewFromUtf8(context->GetIsolate(), &json[0], v8::NewStringType::kNormal).ToLocalChecked()); 27 | if (value_.IsEmpty()) { 28 | return v8::Local(); 29 | } 30 | return value_.ToLocalChecked()->ToObject(context).ToLocalChecked(); 31 | } 32 | 33 | static inline std::string getPropertyFromJson(v8::Isolate* isolate, const v8::Local &jsonObject, const std::string &propertyName) { 34 | v8::Local property = jsonObject->Get(isolate->GetCurrentContext(), v8::String::NewFromUtf8(isolate, propertyName.c_str(), v8::NewStringType::kNormal).ToLocalChecked()).ToLocalChecked(); 35 | v8::String::Utf8Value utf8Value(isolate, property); 36 | return *utf8Value; 37 | } 38 | 39 | static std::string readFileContent(const std::string &filename) { 40 | std::ifstream file(filename); 41 | if (!file.is_open()) { 42 | std:: cerr << "Could not open the file: " << filename << std::endl; 43 | return ""; 44 | } 45 | std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); 46 | return content; 47 | } 48 | 49 | static std::string getExceptionMessage(v8::Isolate* isolate, const v8::Local &exception) { 50 | v8::Local error = v8::Local::Cast(exception); 51 | v8::String::Utf8Value exceptionMessage(isolate, error); 52 | return *exceptionMessage; 53 | } 54 | 55 | static bool compileScript(const v8::Local& context, const v8::Local &source, const std::string &filePath, v8::Local &script, const v8::TryCatch &tryCatch) { 56 | const auto isolate_ = context->GetIsolate(); 57 | v8::ScriptOrigin scriptOrigin = v8::ScriptOrigin( 58 | v8::String::NewFromUtf8( 59 | isolate_, 60 | ("file://" + filePath).c_str(), 61 | v8::NewStringType::kNormal 62 | ).ToLocalChecked() 63 | ); 64 | v8::MaybeLocal script_ = v8::Script::Compile(context, source, &scriptOrigin); 65 | if (!script_.IsEmpty()) { 66 | script = script_.ToLocalChecked(); 67 | } 68 | return !tryCatch.HasCaught(); 69 | } 70 | 71 | static bool executeScript(const v8::Local& context, const v8::Local &script, const v8::TryCatch &tryCatch) { 72 | script->Run(context).ToLocalChecked(); 73 | return !tryCatch.HasCaught(); 74 | } 75 | 76 | static bool runScript(const v8::Local& context, const std::string &filePath) { 77 | std::string fileContent = readFileContent(filePath); 78 | 79 | const auto& isolate_ = context->GetIsolate(); 80 | v8::Local script; 81 | v8::TryCatch tryCatch(isolate_); 82 | v8::Local source = v8::String::NewFromUtf8( 83 | isolate_, 84 | fileContent.c_str(), 85 | v8::NewStringType::kNormal 86 | ).ToLocalChecked(); 87 | 88 | if (!compileScript(context, source, filePath, script, tryCatch)) { 89 | std::cerr << "could not compile the script" << std::endl; 90 | std::cerr << "Exception: " << getExceptionMessage(isolate_, tryCatch.Exception()) << std::endl; 91 | return false; 92 | } 93 | if (!executeScript(context, script, tryCatch)) { 94 | std::cerr << "could not execute the script" << std::endl; 95 | std::cerr << "Exception: " << getExceptionMessage(isolate_, tryCatch.Exception()) << std::endl; 96 | return false; 97 | } 98 | 99 | return true; 100 | } 101 | 102 | #endif // UTILS_H 103 | -------------------------------------------------------------------------------- /src/v8_inspector_listener_impl.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "v8inspector_listener.h" 3 | #include "utils.h" 4 | 5 | #ifndef BASEV8INSPECTORLISTENERIMPL_H 6 | #define BASEV8INSPECTORLISTENERIMPL_H 7 | 8 | class BaseV8InspectorListenerImpl final: public V8InspectorListener { 9 | public: 10 | void onConnected(const v8::Local& context) override { 11 | // Absolute or relative path of JavaScript source file to debug. 12 | // V8 Inspector is very powerful, it has the source map support! 13 | // The TypeScript source file has to be inline source mapped in the JavaScript file. 14 | const std::string filePath = "../example/code.js"; 15 | runScript(context, filePath); 16 | } 17 | }; 18 | 19 | #endif //BASEV8INSPECTORLISTENERIMPL_H 20 | -------------------------------------------------------------------------------- /src/v8inspector_channel.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "v8inspector_channel.h" 3 | #include "utils.h" 4 | 5 | V8InspectorChannelImp::V8InspectorChannelImp(v8::Isolate *isolate, const std::function &onResponse) { 6 | isolate_ = isolate; 7 | onResponse_ = onResponse; 8 | } 9 | 10 | void V8InspectorChannelImp::sendResponse(int callId, std::unique_ptr message) { 11 | const std::string response = convertToString(isolate_, message->string()); 12 | onResponse_(response); 13 | } 14 | 15 | void V8InspectorChannelImp::sendNotification(std::unique_ptr message) { 16 | const std::string notification = convertToString(isolate_, message->string()); 17 | onResponse_(notification); 18 | } 19 | 20 | void V8InspectorChannelImp::flushProtocolNotifications() { 21 | // flush protocol notification 22 | } 23 | -------------------------------------------------------------------------------- /src/v8inspector_channel.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef V8INSPECTORCHANNELIMP_H 6 | #define V8INSPECTORCHANNELIMP_H 7 | 8 | 9 | class V8InspectorChannelImp final: public v8_inspector::V8Inspector::Channel 10 | { 11 | public: 12 | V8InspectorChannelImp(v8::Isolate* isolate, const std::function &onResponse); 13 | 14 | void sendResponse(int callId, std::unique_ptr message) override; 15 | 16 | void sendNotification(std::unique_ptr message) override; 17 | 18 | void flushProtocolNotifications() override; 19 | 20 | private: 21 | v8::Isolate* isolate_; 22 | std::function onResponse_; 23 | }; 24 | 25 | #endif // V8INSPECTORCHANNELIMP_H 26 | -------------------------------------------------------------------------------- /src/v8inspector_client.cpp: -------------------------------------------------------------------------------- 1 | #include "v8inspector_client.h" 2 | 3 | V8InspectorClientImpl::V8InspectorClientImpl(const std::unique_ptr &platform, const v8::Local &context, const std::function &onResponse, const std::function &onWaitFrontendMessageOnPause) { 4 | platform_ = platform.get(); 5 | context_ = context; 6 | onWaitFrontendMessageOnPause_ = onWaitFrontendMessageOnPause; 7 | isolate_ = context_->GetIsolate(); 8 | channel_.reset(new V8InspectorChannelImp(isolate_, onResponse)); 9 | inspector_ = v8_inspector::V8Inspector::create(isolate_, this); 10 | session_ = inspector_->connect(kContextGroupId, channel_.get(), v8_inspector::StringView()); 11 | context_->SetAlignedPointerInEmbedderData(1, this); 12 | 13 | v8_inspector::StringView contextName = convertToStringView("inspector"); 14 | inspector_->contextCreated(v8_inspector::V8ContextInfo(context, kContextGroupId, contextName)); 15 | terminated_ = true; 16 | run_nested_loop_ = false; 17 | } 18 | 19 | void V8InspectorClientImpl::dispatchProtocolMessage(const v8_inspector::StringView &message_view) { 20 | session_->dispatchProtocolMessage(message_view); 21 | } 22 | 23 | void V8InspectorClientImpl::runMessageLoopOnPause(int contextGroupId) { 24 | if (run_nested_loop_) { 25 | return; 26 | } 27 | terminated_ = false; 28 | run_nested_loop_ = true; 29 | while (!terminated_ && onWaitFrontendMessageOnPause_()) { 30 | while (v8::platform::PumpMessageLoop(platform_, isolate_)) {} 31 | } 32 | terminated_ = true; 33 | run_nested_loop_ = false; 34 | } 35 | 36 | void V8InspectorClientImpl::quitMessageLoopOnPause() { 37 | terminated_ = true; 38 | } 39 | 40 | v8::Local V8InspectorClientImpl::ensureDefaultContextInGroup(int contextGroupId) { 41 | return context_; 42 | } 43 | 44 | void V8InspectorClientImpl::schedulePauseOnNextStatement(const v8_inspector::StringView &reason) { 45 | session_->schedulePauseOnNextStatement(reason, reason); 46 | } 47 | 48 | void V8InspectorClientImpl::waitFrontendMessageOnPause() { 49 | terminated_ = false; 50 | } 51 | -------------------------------------------------------------------------------- /src/v8inspector_client.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "v8inspector_channel.h" 6 | #include "utils.h" 7 | 8 | #ifndef V8INSPECTORCLIENTIMPL_H 9 | #define V8INSPECTORCLIENTIMPL_H 10 | 11 | class V8InspectorClientImpl final: public v8_inspector::V8InspectorClient { 12 | public: 13 | V8InspectorClientImpl(const std::unique_ptr &platform, const v8::Local& context, const std::function &onResponse, const std::function &onWaitFrontendMessageOnPause); 14 | 15 | void dispatchProtocolMessage(const v8_inspector::StringView &message_view); 16 | 17 | void runMessageLoopOnPause(int contextGroupId) override; 18 | 19 | void quitMessageLoopOnPause() override; 20 | 21 | void schedulePauseOnNextStatement(const v8_inspector::StringView &reason); 22 | 23 | void waitFrontendMessageOnPause(); 24 | private: 25 | v8::Local ensureDefaultContextInGroup(int contextGroupId) override; 26 | 27 | static const int kContextGroupId = 1; 28 | v8::Platform* platform_; 29 | std::unique_ptr inspector_; 30 | std::unique_ptr session_; 31 | std::unique_ptr channel_; 32 | v8::Isolate* isolate_; 33 | v8::Handle context_; 34 | std::function onWaitFrontendMessageOnPause_; 35 | uint8_t terminated_ = 0; 36 | uint8_t run_nested_loop_ = 0; 37 | }; 38 | 39 | #endif // V8INSPECTORCLIENTIMPL_H 40 | -------------------------------------------------------------------------------- /src/v8inspector_listener.h: -------------------------------------------------------------------------------- 1 | #ifndef V8_INSPECTOR_LISTENER_H 2 | #define V8_INSPECTOR_LISTENER_H 3 | 4 | struct V8InspectorListener { 5 | virtual void onConnected(const v8::Local& context) = 0; 6 | }; 7 | 8 | #endif //V8_INSPECTOR_LISTENER_H 9 | -------------------------------------------------------------------------------- /src/websocket_server.cpp: -------------------------------------------------------------------------------- 1 | #include "websocket_server.h" 2 | 3 | WebSocketServer::WebSocketServer(int port, std::function onMessage) 4 | { 5 | port_ = port; 6 | onMessage_ = std::move(onMessage); 7 | } 8 | 9 | void WebSocketServer::run() { 10 | try 11 | { 12 | auto const address = net::ip::make_address("127.0.0.1"); 13 | net::io_context ioc{1}; 14 | tcp::acceptor acceptor{ioc, {address, static_cast(port_)}}; 15 | printListeningMessage(); 16 | 17 | tcp::socket socket{ioc}; 18 | acceptor.accept(socket); 19 | ws_ = std::unique_ptr>(new websocket::stream(std::move(socket))); 20 | startListening(); 21 | } 22 | catch (const std::exception& e) 23 | { 24 | std::cerr << "Error: " << e.what() << std::endl; 25 | } 26 | } 27 | 28 | void WebSocketServer::sendMessage(const std::string &message) 29 | { 30 | try { 31 | boost::beast::multi_buffer b; 32 | boost::beast::ostream(b) << message; 33 | 34 | ws_->text(ws_->got_text()); 35 | ws_->write(b.data()); 36 | } catch(beast::system_error const& se) { 37 | if (se.code() != websocket::error::closed) 38 | std::cerr << "Error: " << se.code().message() << std::endl; 39 | } catch(std::exception const& e) 40 | { 41 | std::cerr << "Error: " << e.what() << std::endl; 42 | } 43 | } 44 | 45 | void WebSocketServer::startListening() 46 | { 47 | try { 48 | ws_->accept(); 49 | while (true) { 50 | waitFrontendMessage(); 51 | } 52 | } catch(beast::system_error const& se) { 53 | if(se.code() != websocket::error::closed) 54 | std::cerr << "Error: " << se.code().message() << std::endl; 55 | } catch(std::exception const& e) { 56 | std::cerr << "Error: " << e.what() << std::endl; 57 | } 58 | } 59 | 60 | void WebSocketServer::printListeningMessage() { 61 | std::cout << "WebSocket based Inspector Agent started" << std::endl; 62 | std::cout << "Open the following link in your Chrome/Chromium browser: devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:" << port_ << std::endl; 63 | } 64 | 65 | void WebSocketServer::waitForFrontendMessageOnPause() { 66 | waitFrontendMessage(); 67 | } 68 | 69 | void WebSocketServer::waitFrontendMessage() 70 | { 71 | beast::flat_buffer buffer; 72 | ws_->read(buffer); 73 | std::string message = boost::beast::buffers_to_string(buffer.data()); 74 | onMessage_(std::move(message)); 75 | } -------------------------------------------------------------------------------- /src/websocket_server.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace beast = boost::beast; // from 10 | namespace http = beast::http; // from 11 | namespace websocket = beast::websocket; // from 12 | namespace net = boost::asio; // from 13 | using tcp = boost::asio::ip::tcp; // from 14 | 15 | #ifndef WEBSOCKETSERVER_H 16 | #define WEBSOCKETSERVER_H 17 | 18 | class WebSocketServer 19 | { 20 | public: 21 | WebSocketServer(int port, std::function onMessage); 22 | 23 | void run(); 24 | void sendMessage(const std::string &message); 25 | void waitForFrontendMessageOnPause(); 26 | private: 27 | void startListening(); 28 | void printListeningMessage(); 29 | void waitFrontendMessage(); 30 | 31 | int port_; 32 | std::function onMessage_; 33 | std::unique_ptr> ws_ = nullptr; 34 | }; 35 | 36 | #endif // WEBSOCKETSERVER_H 37 | --------------------------------------------------------------------------------