├── .bazelrc ├── .github └── workflows │ ├── copy.bara.sky │ ├── download_extra_srcs.sh │ ├── tests.yml │ └── update.yml ├── .gitignore ├── AUTHORS ├── BUILD.bazel ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── WORKSPACE ├── include ├── 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-handle.h │ ├── heap-state.h │ ├── heap-statistics.h │ ├── heap.h │ ├── internal │ │ ├── api-constants.h │ │ ├── atomic-entry-flag.h │ │ ├── base-page-handle.h │ │ ├── caged-heap-local-data.h │ │ ├── caged-heap.h │ │ ├── compiler-specific.h │ │ ├── finalizer-trait.h │ │ ├── gc-info.h │ │ ├── logging.h │ │ ├── member-storage.h │ │ ├── name-trait.h │ │ ├── persistent-node.h │ │ ├── pointer-policies.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 ├── libplatform │ ├── DEPS │ ├── libplatform-export.h │ ├── libplatform.h │ └── v8-tracing.h ├── v8-platform.h └── v8config.h ├── repositories.bzl ├── samples └── cppgc │ ├── OWNERS │ └── hello-world.cc ├── src ├── base │ ├── DEPS │ ├── DIR_METADATA │ ├── OWNERS │ ├── address-region.h │ ├── atomic-utils.h │ ├── atomicops.h │ ├── base-export.h │ ├── bit-field.h │ ├── bits-iterator.h │ ├── bits.cc │ ├── bits.h │ ├── bounded-page-allocator.cc │ ├── bounded-page-allocator.h │ ├── bounds.h │ ├── build_config.h │ ├── chromium │ │ └── trace_event_common.h │ ├── compiler-specific.h │ ├── container-utils.h │ ├── cpu.cc │ ├── cpu.h │ ├── debug │ │ ├── stack_trace.cc │ │ ├── stack_trace.h │ │ ├── stack_trace_android.cc │ │ ├── stack_trace_fuchsia.cc │ │ ├── stack_trace_posix.cc │ │ └── stack_trace_win.cc │ ├── division-by-constant.cc │ ├── division-by-constant.h │ ├── emulated-virtual-address-subspace.cc │ ├── emulated-virtual-address-subspace.h │ ├── enum-set.h │ ├── export-template.h │ ├── file-utils.cc │ ├── file-utils.h │ ├── flags.h │ ├── free_deleter.h │ ├── functional.h │ ├── hashmap-entry.h │ ├── hashmap.h │ ├── ieee754.cc │ ├── ieee754.h │ ├── immediate-crash.h │ ├── iterator.h │ ├── lazy-instance.h │ ├── logging.cc │ ├── logging.h │ ├── macros.h │ ├── memory.h │ ├── numbers │ │ ├── bignum-dtoa.cc │ │ ├── bignum-dtoa.h │ │ ├── bignum.cc │ │ ├── bignum.h │ │ ├── cached-powers.cc │ │ ├── cached-powers.h │ │ ├── diy-fp.cc │ │ ├── diy-fp.h │ │ ├── double.h │ │ ├── dtoa.cc │ │ ├── dtoa.h │ │ ├── fast-dtoa.cc │ │ ├── fast-dtoa.h │ │ ├── fixed-dtoa.cc │ │ ├── fixed-dtoa.h │ │ ├── strtod.cc │ │ └── strtod.h │ ├── once.cc │ ├── once.h │ ├── optional.h │ ├── overflowing-math.h │ ├── page-allocator.cc │ ├── page-allocator.h │ ├── platform │ │ ├── DIR_METADATA │ │ ├── OWNERS │ │ ├── condition-variable.cc │ │ ├── condition-variable.h │ │ ├── elapsed-timer.h │ │ ├── memory-protection-key.cc │ │ ├── memory-protection-key.h │ │ ├── memory.h │ │ ├── mutex.cc │ │ ├── mutex.h │ │ ├── platform-aix.cc │ │ ├── platform-cygwin.cc │ │ ├── platform-darwin.cc │ │ ├── platform-freebsd.cc │ │ ├── platform-fuchsia.cc │ │ ├── platform-linux.cc │ │ ├── platform-linux.h │ │ ├── platform-macos.cc │ │ ├── platform-openbsd.cc │ │ ├── platform-posix-time.cc │ │ ├── platform-posix-time.h │ │ ├── platform-posix.cc │ │ ├── platform-posix.h │ │ ├── platform-qnx.cc │ │ ├── platform-solaris.cc │ │ ├── platform-starboard.cc │ │ ├── platform-win32.cc │ │ ├── platform.h │ │ ├── semaphore.cc │ │ ├── semaphore.h │ │ ├── time.cc │ │ ├── time.h │ │ ├── wrappers.h │ │ └── yield-processor.h │ ├── pointer-with-payload.h │ ├── qnx-math.h │ ├── region-allocator.cc │ ├── region-allocator.h │ ├── ring-buffer.h │ ├── safe_conversions.h │ ├── safe_conversions_arm_impl.h │ ├── safe_conversions_impl.h │ ├── sanitizer │ │ ├── asan.h │ │ ├── lsan-page-allocator.cc │ │ ├── lsan-page-allocator.h │ │ ├── lsan-virtual-address-space.cc │ │ ├── lsan-virtual-address-space.h │ │ ├── lsan.h │ │ ├── msan.h │ │ └── tsan.h │ ├── small-vector.h │ ├── string-format.h │ ├── strings.cc │ ├── strings.h │ ├── sys-info.cc │ ├── sys-info.h │ ├── template-utils.h │ ├── threaded-list.h │ ├── timezone-cache.h │ ├── ubsan.cc │ ├── utils │ │ ├── random-number-generator.cc │ │ └── random-number-generator.h │ ├── v8-fallthrough.h │ ├── vector.h │ ├── virtual-address-space-page-allocator.cc │ ├── virtual-address-space-page-allocator.h │ ├── virtual-address-space.cc │ ├── virtual-address-space.h │ ├── vlq-base64.cc │ ├── vlq-base64.h │ ├── vlq.h │ └── win32-headers.h ├── heap │ ├── base │ │ ├── active-system-pages.cc │ │ ├── active-system-pages.h │ │ ├── asm │ │ │ ├── arm │ │ │ │ └── push_registers_asm.cc │ │ │ ├── arm64 │ │ │ │ ├── push_registers_asm.cc │ │ │ │ └── push_registers_masm.S │ │ │ ├── ia32 │ │ │ │ ├── push_registers_asm.cc │ │ │ │ └── push_registers_masm.asm │ │ │ ├── loong64 │ │ │ │ └── push_registers_asm.cc │ │ │ ├── mips64 │ │ │ │ └── push_registers_asm.cc │ │ │ ├── ppc │ │ │ │ └── push_registers_asm.cc │ │ │ ├── riscv │ │ │ │ └── push_registers_asm.cc │ │ │ ├── s390 │ │ │ │ └── push_registers_asm.cc │ │ │ └── x64 │ │ │ │ ├── push_registers_asm.cc │ │ │ │ └── push_registers_masm.asm │ │ ├── basic-slot-set.h │ │ ├── stack.cc │ │ ├── stack.h │ │ ├── worklist.cc │ │ └── worklist.h │ └── cppgc │ │ ├── DEPS │ │ ├── allocation.cc │ │ ├── caged-heap-local-data.cc │ │ ├── caged-heap.cc │ │ ├── caged-heap.h │ │ ├── compaction-worklists.cc │ │ ├── compaction-worklists.h │ │ ├── compactor.cc │ │ ├── compactor.h │ │ ├── concurrent-marker.cc │ │ ├── concurrent-marker.h │ │ ├── explicit-management.cc │ │ ├── free-list.cc │ │ ├── free-list.h │ │ ├── garbage-collector.h │ │ ├── gc-info-table.cc │ │ ├── gc-info-table.h │ │ ├── gc-info.cc │ │ ├── gc-invoker.cc │ │ ├── gc-invoker.h │ │ ├── globals.h │ │ ├── heap-base.cc │ │ ├── heap-base.h │ │ ├── heap-config.h │ │ ├── heap-consistency.cc │ │ ├── heap-growing.cc │ │ ├── heap-growing.h │ │ ├── heap-object-header.cc │ │ ├── heap-object-header.h │ │ ├── heap-page.cc │ │ ├── heap-page.h │ │ ├── heap-space.cc │ │ ├── heap-space.h │ │ ├── heap-state.cc │ │ ├── heap-statistics-collector.cc │ │ ├── heap-statistics-collector.h │ │ ├── heap-visitor.h │ │ ├── heap.cc │ │ ├── heap.h │ │ ├── incremental-marking-schedule.cc │ │ ├── incremental-marking-schedule.h │ │ ├── liveness-broker.cc │ │ ├── liveness-broker.h │ │ ├── logging.cc │ │ ├── marker.cc │ │ ├── marker.h │ │ ├── marking-state.cc │ │ ├── marking-state.h │ │ ├── marking-verifier.cc │ │ ├── marking-verifier.h │ │ ├── marking-visitor.cc │ │ ├── marking-visitor.h │ │ ├── marking-worklists.cc │ │ ├── marking-worklists.h │ │ ├── member-storage.cc │ │ ├── member-storage.h │ │ ├── memory.cc │ │ ├── memory.h │ │ ├── metric-recorder.h │ │ ├── name-trait.cc │ │ ├── object-allocator.cc │ │ ├── object-allocator.h │ │ ├── object-poisoner.h │ │ ├── object-size-trait.cc │ │ ├── object-start-bitmap.h │ │ ├── object-view.h │ │ ├── page-memory.cc │ │ ├── page-memory.h │ │ ├── persistent-node.cc │ │ ├── platform.cc │ │ ├── platform.h │ │ ├── pointer-policies.cc │ │ ├── prefinalizer-handler.cc │ │ ├── prefinalizer-handler.h │ │ ├── process-heap-statistics.cc │ │ ├── process-heap-statistics.h │ │ ├── process-heap.cc │ │ ├── process-heap.h │ │ ├── raw-heap.cc │ │ ├── raw-heap.h │ │ ├── remembered-set.cc │ │ ├── remembered-set.h │ │ ├── source-location.cc │ │ ├── stats-collector.cc │ │ ├── stats-collector.h │ │ ├── sweeper.cc │ │ ├── sweeper.h │ │ ├── task-handle.h │ │ ├── testing.cc │ │ ├── trace-event.h │ │ ├── trace-trait.cc │ │ ├── unmarker.h │ │ ├── virtual-memory.cc │ │ ├── virtual-memory.h │ │ ├── visitor.cc │ │ ├── visitor.h │ │ ├── write-barrier.cc │ │ └── write-barrier.h ├── libplatform │ ├── DEPS │ ├── DIR_METADATA │ ├── OWNERS │ ├── default-foreground-task-runner.cc │ ├── default-foreground-task-runner.h │ ├── default-job.cc │ ├── default-job.h │ ├── default-platform.cc │ ├── default-platform.h │ ├── default-worker-threads-task-runner.cc │ ├── default-worker-threads-task-runner.h │ ├── delayed-task-queue.cc │ ├── delayed-task-queue.h │ ├── etw │ │ └── etw-provider-win.h │ ├── task-queue.cc │ ├── task-queue.h │ ├── tracing │ │ ├── DEPS │ │ ├── OWNERS │ │ ├── recorder-mac.cc │ │ ├── recorder-win.cc │ │ ├── recorder.h │ │ ├── trace-buffer.cc │ │ ├── trace-buffer.h │ │ ├── trace-config.cc │ │ ├── trace-event-listener.cc │ │ ├── trace-event-listener.h │ │ ├── trace-object.cc │ │ ├── trace-writer.cc │ │ ├── trace-writer.h │ │ └── tracing-controller.cc │ ├── worker-thread.cc │ └── worker-thread.h └── tracing │ └── trace-event.h ├── test └── unittests │ └── heap │ └── cppgc │ ├── age-table-unittest.cc │ ├── allocation-unittest.cc │ ├── compactor-unittest.cc │ ├── concurrent-marking-unittest.cc │ ├── concurrent-sweeper-unittest.cc │ ├── cross-thread-persistent-unittest.cc │ ├── custom-spaces-unittest.cc │ ├── ephemeron-pair-unittest.cc │ ├── explicit-management-unittest.cc │ ├── finalizer-trait-unittest.cc │ ├── free-list-unittest.cc │ ├── garbage-collected-unittest.cc │ ├── gc-info-unittest.cc │ ├── gc-invoker-unittest.cc │ ├── heap-growing-unittest.cc │ ├── heap-object-header-unittest.cc │ ├── heap-page-unittest.cc │ ├── heap-registry-unittest.cc │ ├── heap-statistics-collector-unittest.cc │ ├── heap-unittest.cc │ ├── incremental-marking-schedule-unittest.cc │ ├── liveness-broker-unittest.cc │ ├── logging-unittest.cc │ ├── marker-unittest.cc │ ├── marking-verifier-unittest.cc │ ├── marking-visitor-unittest.cc │ ├── member-unittest.cc │ ├── metric-recorder-unittest.cc │ ├── minor-gc-unittest.cc │ ├── name-trait-unittest.cc │ ├── object-size-trait-unittest.cc │ ├── object-start-bitmap-unittest.cc │ ├── page-memory-unittest.cc │ ├── persistent-family-unittest.cc │ ├── platform-unittest.cc │ ├── prefinalizer-unittest.cc │ ├── run-all-unittests.cc │ ├── sanitizer-unittest.cc │ ├── source-location-unittest.cc │ ├── stack-unittest.cc │ ├── stats-collector-scopes-unittest.cc │ ├── stats-collector-unittest.cc │ ├── sweeper-unittest.cc │ ├── test-platform.cc │ ├── test-platform.h │ ├── testing-unittest.cc │ ├── tests.cc │ ├── tests.h │ ├── visitor-unittest.cc │ ├── weak-container-unittest.cc │ ├── workloads-unittest.cc │ └── write-barrier-unittest.cc └── testing ├── OWNERS ├── gmock-support.h ├── gmock ├── BUILD.gn ├── OWNERS └── include │ ├── DEPS │ └── gmock │ ├── gmock-actions.h │ ├── gmock-matchers.h │ └── gmock.h ├── gtest-support.h └── gtest ├── BUILD.gn ├── OWNERS ├── empty.cc └── include ├── DEPS └── gtest ├── gtest-death-test.h ├── gtest-message.h ├── gtest-param-test.h ├── gtest-spi.h ├── gtest.h └── gtest_prod.h /.bazelrc: -------------------------------------------------------------------------------- 1 | build --copt=-std=c++17 2 | -------------------------------------------------------------------------------- /.github/workflows/download_extra_srcs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | chromium_trace_common_header="$PWD/src/base/chromium/trace_event_common.h" 4 | mkdir -p $(dirname $chromium_trace_common_header) 5 | curl "https://raw.githubusercontent.com/chromium/chromium/main/base/trace_event/common/trace_event_common.h" -SLo "$chromium_trace_common_header" 6 | 7 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | all_tests: 6 | name: Test ${{ matrix.name }} 7 | runs-on: ${{ matrix.os }} 8 | defaults: 9 | run: 10 | shell: bash 11 | strategy: 12 | matrix: 13 | include: 14 | - name: Linux 15 | os: ubuntu-latest 16 | mode: opt 17 | - name: MacOS 18 | os: macos-latest 19 | mode: opt 20 | # TODO: Enable windows support 21 | # - os: windows-latest 22 | steps: 23 | - name: Checkout the source 24 | uses: actions/checkout@v2 25 | - name: Test with Bazel 26 | run: | 27 | bazel test --compilation_mode=${{ matrix.mode }} ...:all --test_output=errors 28 | 29 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | name: Update CPPGC 2 | 3 | on: 4 | schedule: 5 | - cron: '0 7 1 * *' 6 | workflow_dispatch: 7 | 8 | permissions: 9 | contents: write 10 | pull-requests: write 11 | 12 | 13 | jobs: 14 | update: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Get Token 18 | id: get_workflow_token 19 | uses: peter-murray/workflow-application-token-action@v1 20 | with: 21 | application_id: ${{ secrets.BOT_ID }} 22 | application_private_key: ${{ secrets.BOT_PRIVATE_KEY }} 23 | - name: Checkout the source 24 | uses: actions/checkout@v2 25 | - name: Download Copybara 26 | shell: bash 27 | run: curl -SLO https://github.com/oilpan-gc/export-automation/releases/download/copybara/copybara_deploy.jar 28 | - name: Create PR 29 | shell: bash 30 | env: 31 | GH_TOKEN: ${{ steps.get_workflow_token.outputs.token }} 32 | run: | 33 | gh auth setup-git 34 | git config --global user.name 'oilpan-gc-automation[bot]' 35 | git config --global user.email '112789766+oilpan-gc-automation[bot]@users.noreply.github.com' 36 | echo "https://x-access-token:${GH_TOKEN}@api.github.com" > ~/.git-credentials 37 | git_temp_dir=/tmp/copybara 38 | mkdir -p $git_temp_dir 39 | java -jar ./copybara_deploy.jar \ 40 | "$PWD/.github/workflows/copy.bara.sky" \ 41 | --git-origin-checkout-hook "$PWD/.github/workflows/download_extra_srcs.sh" \ 42 | --git-destination-path $git_temp_dir 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bazel-* 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # V8 Code of Conduct 2 | 3 | As part of the Chromium team, the V8 team is committed to preserving and 4 | fostering a diverse, welcoming community. To this end, the [Chromium Code of 5 | Conduct](https://chromium.googlesource.com/chromium/src/+/master/CODE_OF_CONDUCT.md) 6 | applies to our repos and organizations, mailing lists, blog content, and any 7 | other Chromium-supported communication group, as well as any private 8 | communication initiated in the context of these spaces. 9 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "cppgc") 2 | 3 | load("@cppgc//:repositories.bzl", "cppgc_repositories") 4 | 5 | cppgc_repositories() 6 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /include/cppgc/OWNERS: -------------------------------------------------------------------------------- 1 | bikineev@chromium.org 2 | omerkatz@chromium.org -------------------------------------------------------------------------------- /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 | #include "v8config.h" // NOLINT(build/include_directory) 9 | 10 | namespace cppgc { 11 | 12 | /** 13 | * Indicator for the stack state of the embedder. 14 | */ 15 | enum class EmbedderStackState { 16 | /** 17 | * Stack may contain interesting heap pointers. 18 | */ 19 | kMayContainHeapPointers, 20 | /** 21 | * Stack does not contain any interesting heap pointers. 22 | */ 23 | kNoHeapPointers, 24 | }; 25 | 26 | } // namespace cppgc 27 | 28 | #endif // INCLUDE_CPPGC_COMMON_H_ 29 | -------------------------------------------------------------------------------- /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 | 10 | #include "cppgc/platform.h" 11 | #include "libplatform/libplatform.h" 12 | #include "v8config.h" // NOLINT(build/include_directory) 13 | 14 | namespace cppgc { 15 | 16 | /** 17 | * Platform provided by cppgc. Uses V8's DefaultPlatform provided by 18 | * libplatform internally. Exception: `GetForegroundTaskRunner()`, see below. 19 | */ 20 | class V8_EXPORT DefaultPlatform : public Platform { 21 | public: 22 | using IdleTaskSupport = v8::platform::IdleTaskSupport; 23 | explicit DefaultPlatform( 24 | int thread_pool_size = 0, 25 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, 26 | std::unique_ptr tracing_controller = {}) 27 | : v8_platform_(v8::platform::NewDefaultPlatform( 28 | thread_pool_size, idle_task_support, 29 | v8::platform::InProcessStackDumping::kDisabled, 30 | std::move(tracing_controller))) {} 31 | 32 | cppgc::PageAllocator* GetPageAllocator() override { 33 | return v8_platform_->GetPageAllocator(); 34 | } 35 | 36 | double MonotonicallyIncreasingTime() override { 37 | return v8_platform_->MonotonicallyIncreasingTime(); 38 | } 39 | 40 | std::shared_ptr GetForegroundTaskRunner() override { 41 | // V8's default platform creates a new task runner when passed the 42 | // `v8::Isolate` pointer the first time. For non-default platforms this will 43 | // require getting the appropriate task runner. 44 | return v8_platform_->GetForegroundTaskRunner(kNoIsolate); 45 | } 46 | 47 | std::unique_ptr PostJob( 48 | cppgc::TaskPriority priority, 49 | std::unique_ptr job_task) override { 50 | return v8_platform_->PostJob(priority, std::move(job_task)); 51 | } 52 | 53 | TracingController* GetTracingController() override { 54 | return v8_platform_->GetTracingController(); 55 | } 56 | 57 | v8::Platform* GetV8Platform() const { return v8_platform_.get(); } 58 | 59 | protected: 60 | static constexpr v8::Isolate* kNoIsolate = nullptr; 61 | 62 | std::unique_ptr v8_platform_; 63 | }; 64 | 65 | } // namespace cppgc 66 | 67 | #endif // INCLUDE_CPPGC_DEFAULT_PLATFORM_H_ 68 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /include/cppgc/heap-handle.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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_HANDLE_H_ 6 | #define INCLUDE_CPPGC_HEAP_HANDLE_H_ 7 | 8 | #include "v8config.h" // NOLINT(build/include_directory) 9 | 10 | namespace cppgc { 11 | 12 | namespace internal { 13 | class HeapBase; 14 | class WriteBarrierTypeForCagedHeapPolicy; 15 | class WriteBarrierTypeForNonCagedHeapPolicy; 16 | } // namespace internal 17 | 18 | /** 19 | * Opaque handle used for additional heap APIs. 20 | */ 21 | class HeapHandle { 22 | private: 23 | HeapHandle() = default; 24 | 25 | V8_INLINE bool is_incremental_marking_in_progress() const { 26 | return is_incremental_marking_in_progress_; 27 | } 28 | 29 | V8_INLINE bool is_young_generation_enabled() const { 30 | return is_young_generation_enabled_; 31 | } 32 | 33 | bool is_incremental_marking_in_progress_ = false; 34 | bool is_young_generation_enabled_ = false; 35 | 36 | friend class internal::HeapBase; 37 | friend class internal::WriteBarrierTypeForCagedHeapPolicy; 38 | friend class internal::WriteBarrierTypeForNonCagedHeapPolicy; 39 | }; 40 | 41 | } // namespace cppgc 42 | 43 | #endif // INCLUDE_CPPGC_HEAP_HANDLE_H_ 44 | -------------------------------------------------------------------------------- /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 | #if defined(V8_TARGET_ARCH_ARM64) && defined(V8_OS_MACOS) 36 | constexpr size_t kGuardPageSize = 0; 37 | #else 38 | constexpr size_t kGuardPageSize = 4096; 39 | #endif 40 | 41 | static constexpr size_t kLargeObjectSizeThreshold = kPageSize / 2; 42 | 43 | #if defined(CPPGC_CAGED_HEAP) 44 | #if defined(CPPGC_2GB_CAGE) 45 | constexpr size_t kCagedHeapReservationSize = static_cast(2) * kGB; 46 | #else // !defined(CPPGC_2GB_CAGE) 47 | constexpr size_t kCagedHeapReservationSize = static_cast(4) * kGB; 48 | #endif // !defined(CPPGC_2GB_CAGE) 49 | constexpr size_t kCagedHeapReservationAlignment = kCagedHeapReservationSize; 50 | #endif // defined(CPPGC_CAGED_HEAP) 51 | 52 | static constexpr size_t kDefaultAlignment = sizeof(void*); 53 | 54 | // Maximum support alignment for a type as in `alignof(T)`. 55 | static constexpr size_t kMaxSupportedAlignment = 2 * kDefaultAlignment; 56 | 57 | // Granularity of heap allocations. 58 | constexpr size_t kAllocationGranularity = sizeof(void*); 59 | 60 | } // namespace api_constants 61 | 62 | } // namespace internal 63 | } // namespace cppgc 64 | 65 | #endif // INCLUDE_CPPGC_INTERNAL_API_CONSTANTS_H_ 66 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /include/cppgc/internal/base-page-handle.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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_BASE_PAGE_HANDLE_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_BASE_PAGE_HANDLE_H_ 7 | 8 | #include "cppgc/heap-handle.h" 9 | #include "cppgc/internal/api-constants.h" 10 | #include "cppgc/internal/logging.h" 11 | #include "v8config.h" // NOLINT(build/include_directory) 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | // The class is needed in the header to allow for fast access to HeapHandle in 17 | // the write barrier. 18 | class BasePageHandle { 19 | public: 20 | static V8_INLINE BasePageHandle* FromPayload(void* payload) { 21 | return reinterpret_cast( 22 | (reinterpret_cast(payload) & 23 | ~(api_constants::kPageSize - 1)) + 24 | api_constants::kGuardPageSize); 25 | } 26 | static V8_INLINE const BasePageHandle* FromPayload(const void* payload) { 27 | return FromPayload(const_cast(payload)); 28 | } 29 | 30 | HeapHandle& heap_handle() { return heap_handle_; } 31 | const HeapHandle& heap_handle() const { return heap_handle_; } 32 | 33 | protected: 34 | explicit BasePageHandle(HeapHandle& heap_handle) : heap_handle_(heap_handle) { 35 | CPPGC_DCHECK(reinterpret_cast(this) % api_constants::kPageSize == 36 | api_constants::kGuardPageSize); 37 | } 38 | 39 | HeapHandle& heap_handle_; 40 | }; 41 | 42 | } // namespace internal 43 | } // namespace cppgc 44 | 45 | #endif // INCLUDE_CPPGC_INTERNAL_BASE_PAGE_HANDLE_H_ 46 | -------------------------------------------------------------------------------- /include/cppgc/internal/caged-heap.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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_H_ 6 | #define INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "cppgc/internal/api-constants.h" 12 | #include "cppgc/internal/base-page-handle.h" 13 | #include "v8config.h" // NOLINT(build/include_directory) 14 | 15 | #if defined(CPPGC_CAGED_HEAP) 16 | 17 | namespace cppgc { 18 | namespace internal { 19 | 20 | class V8_EXPORT CagedHeapBase { 21 | public: 22 | V8_INLINE static uintptr_t OffsetFromAddress(const void* address) { 23 | return reinterpret_cast(address) & 24 | (api_constants::kCagedHeapReservationAlignment - 1); 25 | } 26 | 27 | V8_INLINE static bool IsWithinCage(const void* address) { 28 | CPPGC_DCHECK(g_heap_base_); 29 | return (reinterpret_cast(address) & 30 | ~(api_constants::kCagedHeapReservationAlignment - 1)) == 31 | g_heap_base_; 32 | } 33 | 34 | V8_INLINE static bool AreWithinCage(const void* addr1, const void* addr2) { 35 | #if defined(CPPGC_2GB_CAGE) 36 | static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT - 1; 37 | #else //! defined(CPPGC_2GB_CAGE) 38 | static constexpr size_t kHalfWordShift = sizeof(uint32_t) * CHAR_BIT; 39 | #endif //! defined(CPPGC_2GB_CAGE) 40 | static_assert((static_cast(1) << kHalfWordShift) == 41 | api_constants::kCagedHeapReservationSize); 42 | CPPGC_DCHECK(g_heap_base_); 43 | return !(((reinterpret_cast(addr1) ^ g_heap_base_) | 44 | (reinterpret_cast(addr2) ^ g_heap_base_)) >> 45 | kHalfWordShift); 46 | } 47 | 48 | V8_INLINE static uintptr_t GetBase() { return g_heap_base_; } 49 | 50 | private: 51 | friend class CagedHeap; 52 | 53 | static uintptr_t g_heap_base_; 54 | }; 55 | 56 | } // namespace internal 57 | } // namespace cppgc 58 | 59 | #endif // defined(CPPGC_CAGED_HEAP) 60 | 61 | #endif // INCLUDE_CPPGC_INTERNAL_CAGED_HEAP_H_ 62 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 defined(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 // !defined(DEBUG) 31 | #define CPPGC_DCHECK_MSG(condition, message) \ 32 | (static_cast(::cppgc::internal::EatParams(condition), message)>{})) 34 | #endif // !defined(DEBUG) 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 the build supports extracting C++ names as object names. 41 | * 42 | * @returns true if C++ names should be hidden and represented by kHiddenName. 43 | */ 44 | static constexpr bool SupportsCppClassNamesAsObjectNames() { 45 | #if CPPGC_SUPPORTS_OBJECT_NAMES 46 | return true; 47 | #else // !CPPGC_SUPPORTS_OBJECT_NAMES 48 | return false; 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* GetHumanReadableName() const = 0; 61 | }; 62 | 63 | } // namespace cppgc 64 | 65 | #endif // INCLUDE_CPPGC_NAME_PROVIDER_H_ 66 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | static constexpr intptr_t kSentinelValue = 0b10; 17 | template 18 | operator T*() const { 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /repositories.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") 3 | 4 | def cppgc_repositories(): 5 | maybe( 6 | repo_rule = http_archive, 7 | name = "platforms", 8 | urls = [ 9 | "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.5/platforms-0.0.5.tar.gz", 10 | "https://github.com/bazelbuild/platforms/releases/download/0.0.5/platforms-0.0.5.tar.gz", 11 | ], 12 | sha256 = "379113459b0feaf6bfbb584a91874c065078aa673222846ac765f86661c27407", 13 | ) 14 | maybe( 15 | repo_rule = http_archive, 16 | name = "com_google_googletest", 17 | urls = ["https://github.com/google/googletest/archive/5126f7166109666a9c0534021fb1a3038659494c.zip"], 18 | strip_prefix = "googletest-5126f7166109666a9c0534021fb1a3038659494c", 19 | sha256 = "d09a503599da941e4990e4ca4adf7b17e26823087cbd14df1742c6f9a6ff7cd6", 20 | ) 21 | maybe( 22 | repo_rule = http_archive, 23 | name = "bazel_skylib", 24 | urls = [ 25 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz", 26 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz", 27 | ], 28 | sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728", 29 | ) 30 | -------------------------------------------------------------------------------- /samples/cppgc/OWNERS: -------------------------------------------------------------------------------- 1 | bikineev@chromium.org 2 | mlippautz@chromium.org 3 | omerkatz@chromium.org 4 | -------------------------------------------------------------------------------- /src/base/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | "-include", 3 | "+include/v8config.h", 4 | "+include/v8-platform.h", 5 | "-src", 6 | "+src/base", 7 | ] 8 | -------------------------------------------------------------------------------- /src/base/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" 11 | } -------------------------------------------------------------------------------- /src/base/OWNERS: -------------------------------------------------------------------------------- 1 | clemensb@chromium.org 2 | ishell@chromium.org 3 | mlippautz@chromium.org 4 | -------------------------------------------------------------------------------- /src/base/base-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_BASE_BASE_EXPORT_H_ 6 | #define V8_BASE_BASE_EXPORT_H_ 7 | 8 | #include "include/v8config.h" 9 | 10 | #if V8_OS_WIN 11 | 12 | #ifdef BUILDING_V8_BASE_SHARED 13 | #define V8_BASE_EXPORT __declspec(dllexport) 14 | #elif USING_V8_BASE_SHARED 15 | #define V8_BASE_EXPORT __declspec(dllimport) 16 | #else 17 | #define V8_BASE_EXPORT 18 | #endif // BUILDING_V8_BASE_SHARED 19 | 20 | #else // !V8_OS_WIN 21 | 22 | // Setup for Linux shared library export. 23 | #ifdef BUILDING_V8_BASE_SHARED 24 | #define V8_BASE_EXPORT __attribute__((visibility("default"))) 25 | #else 26 | #define V8_BASE_EXPORT 27 | #endif 28 | 29 | #endif // V8_OS_WIN 30 | 31 | #endif // V8_BASE_BASE_EXPORT_H_ 32 | -------------------------------------------------------------------------------- /src/base/bits-iterator.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_BASE_BITS_ITERATOR_H_ 6 | #define V8_BASE_BITS_ITERATOR_H_ 7 | 8 | #include 9 | 10 | #include "src/base/bits.h" 11 | #include "src/base/iterator.h" 12 | 13 | namespace v8 { 14 | namespace base { 15 | namespace bits { 16 | 17 | template 18 | class BitsIterator : public iterator { 19 | static_assert(std::is_integral::value); 20 | 21 | public: 22 | explicit BitsIterator(T bits) : bits_(bits) {} 23 | 24 | int operator*() const { 25 | return kMSBFirst ? 8 * sizeof(T) - 1 - CountLeadingZeros(bits_) 26 | : CountTrailingZeros(bits_); 27 | } 28 | 29 | BitsIterator& operator++() { 30 | bits_ &= ~(T{1} << **this); 31 | return *this; 32 | } 33 | 34 | bool operator==(BitsIterator other) { return bits_ == other.bits_; } 35 | bool operator!=(BitsIterator other) { return bits_ != other.bits_; } 36 | 37 | private: 38 | T bits_; 39 | }; 40 | 41 | // Returns an iterable over the bits in {bits}, from LSB to MSB. 42 | template 43 | auto IterateBits(T bits) { 44 | return make_iterator_range(BitsIterator{bits}, BitsIterator{0}); 45 | } 46 | 47 | // Returns an iterable over the bits in {bits}, from MSB to LSB. 48 | template 49 | auto IterateBitsBackwards(T bits) { 50 | return make_iterator_range(BitsIterator{bits}, 51 | BitsIterator{0}); 52 | } 53 | 54 | } // namespace bits 55 | } // namespace base 56 | } // namespace v8 57 | 58 | #endif // V8_BASE_BITS_ITERATOR_H_ 59 | -------------------------------------------------------------------------------- /src/base/bounds.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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_BASE_BOUNDS_H_ 6 | #define V8_BASE_BOUNDS_H_ 7 | 8 | #include "include/v8config.h" 9 | #include "src/base/macros.h" 10 | 11 | namespace v8 { 12 | namespace base { 13 | 14 | // Checks if value is in range [lower_limit, higher_limit] using a single 15 | // branch. 16 | template 17 | inline constexpr bool IsInRange(T value, U lower_limit, U higher_limit) { 18 | DCHECK_LE(lower_limit, higher_limit); 19 | static_assert(sizeof(U) <= sizeof(T)); 20 | using unsigned_T = typename std::make_unsigned::type; 21 | // Use static_cast to support enum classes. 22 | return static_cast(static_cast(value) - 23 | static_cast(lower_limit)) <= 24 | static_cast(static_cast(higher_limit) - 25 | static_cast(lower_limit)); 26 | } 27 | 28 | // Checks if [index, index+length) is in range [0, max). Note that this check 29 | // works even if {index+length} would wrap around. 30 | template ::value>::type> 32 | inline constexpr bool IsInBounds(T index, T length, T max) { 33 | return length <= max && index <= (max - length); 34 | } 35 | 36 | // Checks if [index, index+length) is in range [0, max). If not, {length} is 37 | // clamped to its valid range. Note that this check works even if 38 | // {index+length} would wrap around. 39 | template 40 | inline bool ClampToBounds(T index, T* length, T max) { 41 | if (index > max) { 42 | *length = 0; 43 | return false; 44 | } 45 | T avail = max - index; 46 | bool oob = *length > avail; 47 | if (oob) *length = avail; 48 | return !oob; 49 | } 50 | 51 | } // namespace base 52 | } // namespace v8 53 | 54 | #endif // V8_BASE_BOUNDS_H_ 55 | -------------------------------------------------------------------------------- /src/base/debug/stack_trace.cc: -------------------------------------------------------------------------------- 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 | #include "src/base/debug/stack_trace.h" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include "src/base/macros.h" 13 | 14 | namespace v8 { 15 | namespace base { 16 | namespace debug { 17 | 18 | StackTrace::StackTrace(const void* const* trace, size_t count) { 19 | count = std::min(count, arraysize(trace_)); 20 | if (count) memcpy(trace_, trace, count * sizeof(trace_[0])); 21 | count_ = count; 22 | } 23 | 24 | StackTrace::~StackTrace() = default; 25 | 26 | const void* const* StackTrace::Addresses(size_t* count) const { 27 | *count = count_; 28 | if (count_) return trace_; 29 | return nullptr; 30 | } 31 | 32 | std::string StackTrace::ToString() const { 33 | std::stringstream stream; 34 | OutputToStream(&stream); 35 | return stream.str(); 36 | } 37 | 38 | } // namespace debug 39 | } // namespace base 40 | } // namespace v8 41 | -------------------------------------------------------------------------------- /src/base/debug/stack_trace_fuchsia.cc: -------------------------------------------------------------------------------- 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 | #include "src/base/debug/stack_trace.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "src/base/platform/platform.h" 11 | 12 | namespace v8 { 13 | namespace base { 14 | namespace debug { 15 | 16 | bool EnableInProcessStackDumping() { 17 | // The system crashlogger captures and prints backtraces which are then 18 | // symbolized by a host-side script that runs addr2line. Because symbols are 19 | // not available on device, there's not much use in implementing in-process 20 | // capture. 21 | return false; 22 | } 23 | 24 | void DisableSignalStackDump() {} 25 | 26 | StackTrace::StackTrace() {} 27 | 28 | void StackTrace::Print() const { 29 | std::string backtrace = ToString(); 30 | OS::Print("%s\n", backtrace.c_str()); 31 | } 32 | 33 | void StackTrace::OutputToStream(std::ostream* os) const { 34 | for (size_t i = 0; i < count_; ++i) { 35 | *os << "#" << std::setw(2) << i << trace_[i] << "\n"; 36 | } 37 | } 38 | 39 | } // namespace debug 40 | } // namespace base 41 | } // namespace v8 42 | -------------------------------------------------------------------------------- /src/base/file-utils.cc: -------------------------------------------------------------------------------- 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 | #include "src/base/file-utils.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "src/base/platform/platform.h" 11 | 12 | namespace v8 { 13 | namespace base { 14 | 15 | std::unique_ptr RelativePath(const char* exec_path, const char* name) { 16 | DCHECK(exec_path); 17 | size_t basename_start = strlen(exec_path); 18 | while (basename_start > 0 && 19 | !OS::isDirectorySeparator(exec_path[basename_start - 1])) { 20 | --basename_start; 21 | } 22 | size_t name_length = strlen(name); 23 | auto buffer = std::make_unique(basename_start + name_length + 1); 24 | if (basename_start > 0) memcpy(buffer.get(), exec_path, basename_start); 25 | memcpy(buffer.get() + basename_start, name, name_length); 26 | return buffer; 27 | } 28 | 29 | } // namespace base 30 | } // namespace v8 31 | -------------------------------------------------------------------------------- /src/base/file-utils.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_BASE_FILE_UTILS_H_ 6 | #define V8_BASE_FILE_UTILS_H_ 7 | 8 | #include 9 | 10 | #include "src/base/base-export.h" 11 | 12 | namespace v8 { 13 | namespace base { 14 | 15 | // Helper functions to manipulate file paths. 16 | 17 | V8_BASE_EXPORT 18 | std::unique_ptr RelativePath(const char* exec_path, const char* name); 19 | 20 | } // namespace base 21 | } // namespace v8 22 | 23 | #endif // V8_BASE_FILE_UTILS_H_ 24 | -------------------------------------------------------------------------------- /src/base/free_deleter.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Chromium 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 | // Slightly adapted for inclusion in V8. 6 | // Copyright 2016 the V8 project authors. All rights reserved. 7 | 8 | #ifndef V8_BASE_FREE_DELETER_H_ 9 | #define V8_BASE_FREE_DELETER_H_ 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "src/base/platform/memory.h" 16 | 17 | namespace v8 { 18 | namespace base { 19 | 20 | // Function object which invokes 'free' on its parameter, which must be 21 | // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr: 22 | // 23 | // std::unique_ptr foo_ptr( 24 | // static_cast(malloc(sizeof(int)))); 25 | struct FreeDeleter { 26 | inline void operator()(void* ptr) const { base::Free(ptr); } 27 | }; 28 | 29 | } // namespace base 30 | } // namespace v8 31 | 32 | #endif // V8_BASE_FREE_DELETER_H_ 33 | -------------------------------------------------------------------------------- /src/base/numbers/cached-powers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 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_BASE_NUMBERS_CACHED_POWERS_H_ 6 | #define V8_BASE_NUMBERS_CACHED_POWERS_H_ 7 | 8 | #include "src/base/numbers/diy-fp.h" 9 | 10 | namespace v8 { 11 | namespace base { 12 | 13 | class PowersOfTenCache { 14 | public: 15 | // Not all powers of ten are cached. The decimal exponent of two neighboring 16 | // cached numbers will differ by kDecimalExponentDistance. 17 | static const int kDecimalExponentDistance; 18 | 19 | static const int kMinDecimalExponent; 20 | static const int kMaxDecimalExponent; 21 | 22 | // Returns a cached power-of-ten with a binary exponent in the range 23 | // [min_exponent; max_exponent] (boundaries included). 24 | static void GetCachedPowerForBinaryExponentRange(int min_exponent, 25 | int max_exponent, 26 | DiyFp* power, 27 | int* decimal_exponent); 28 | 29 | // Returns a cached power of ten x ~= 10^k such that 30 | // k <= decimal_exponent < k + kCachedPowersDecimalDistance. 31 | // The given decimal_exponent must satisfy 32 | // kMinDecimalExponent <= requested_exponent, and 33 | // requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance. 34 | static void GetCachedPowerForDecimalExponent(int requested_exponent, 35 | DiyFp* power, 36 | int* found_exponent); 37 | }; 38 | 39 | } // namespace base 40 | } // namespace v8 41 | 42 | #endif // V8_BASE_NUMBERS_CACHED_POWERS_H_ 43 | -------------------------------------------------------------------------------- /src/base/numbers/diy-fp.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 | #include "src/base/numbers/diy-fp.h" 6 | 7 | #include 8 | 9 | namespace v8 { 10 | namespace base { 11 | 12 | void DiyFp::Multiply(const DiyFp& other) { 13 | // Simply "emulates" a 128 bit multiplication. 14 | // However: the resulting number only contains 64 bits. The least 15 | // significant 64 bits are only used for rounding the most significant 64 16 | // bits. 17 | const uint64_t kM32 = 0xFFFFFFFFu; 18 | uint64_t a = f_ >> 32; 19 | uint64_t b = f_ & kM32; 20 | uint64_t c = other.f_ >> 32; 21 | uint64_t d = other.f_ & kM32; 22 | uint64_t ac = a * c; 23 | uint64_t bc = b * c; 24 | uint64_t ad = a * d; 25 | uint64_t bd = b * d; 26 | uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32); 27 | // By adding 1U << 31 to tmp we round the final result. 28 | // Halfway cases will be round up. 29 | tmp += 1U << 31; 30 | uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); 31 | e_ += other.e_ + 64; 32 | f_ = result_f; 33 | } 34 | 35 | } // namespace base 36 | } // namespace v8 37 | -------------------------------------------------------------------------------- /src/base/numbers/dtoa.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 | #include "src/base/numbers/dtoa.h" 6 | 7 | #include 8 | 9 | #include "src/base/logging.h" 10 | #include "src/base/numbers/bignum-dtoa.h" 11 | #include "src/base/numbers/double.h" 12 | #include "src/base/numbers/fast-dtoa.h" 13 | #include "src/base/numbers/fixed-dtoa.h" 14 | 15 | namespace v8 { 16 | namespace base { 17 | 18 | static BignumDtoaMode DtoaToBignumDtoaMode(DtoaMode dtoa_mode) { 19 | switch (dtoa_mode) { 20 | case DTOA_SHORTEST: 21 | return BIGNUM_DTOA_SHORTEST; 22 | case DTOA_FIXED: 23 | return BIGNUM_DTOA_FIXED; 24 | case DTOA_PRECISION: 25 | return BIGNUM_DTOA_PRECISION; 26 | default: 27 | UNREACHABLE(); 28 | } 29 | } 30 | 31 | void DoubleToAscii(double v, DtoaMode mode, int requested_digits, 32 | Vector buffer, int* sign, int* length, int* point) { 33 | DCHECK(!Double(v).IsSpecial()); 34 | DCHECK(mode == DTOA_SHORTEST || requested_digits >= 0); 35 | 36 | if (Double(v).Sign() < 0) { 37 | *sign = 1; 38 | v = -v; 39 | } else { 40 | *sign = 0; 41 | } 42 | 43 | if (v == 0) { 44 | buffer[0] = '0'; 45 | buffer[1] = '\0'; 46 | *length = 1; 47 | *point = 1; 48 | return; 49 | } 50 | 51 | if (mode == DTOA_PRECISION && requested_digits == 0) { 52 | buffer[0] = '\0'; 53 | *length = 0; 54 | return; 55 | } 56 | 57 | bool fast_worked; 58 | switch (mode) { 59 | case DTOA_SHORTEST: 60 | fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, length, point); 61 | break; 62 | case DTOA_FIXED: 63 | fast_worked = FastFixedDtoa(v, requested_digits, buffer, length, point); 64 | break; 65 | case DTOA_PRECISION: 66 | fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, buffer, 67 | length, point); 68 | break; 69 | default: 70 | UNREACHABLE(); 71 | } 72 | if (fast_worked) return; 73 | 74 | // If the fast dtoa didn't succeed use the slower bignum version. 75 | BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); 76 | BignumDtoa(v, bignum_mode, requested_digits, buffer, length, point); 77 | buffer[*length] = '\0'; 78 | } 79 | 80 | } // namespace base 81 | } // namespace v8 82 | -------------------------------------------------------------------------------- /src/base/numbers/fixed-dtoa.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 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_BASE_NUMBERS_FIXED_DTOA_H_ 6 | #define V8_BASE_NUMBERS_FIXED_DTOA_H_ 7 | 8 | #include "src/base/vector.h" 9 | 10 | namespace v8 { 11 | namespace base { 12 | 13 | // Produces digits necessary to print a given number with 14 | // 'fractional_count' digits after the decimal point. 15 | // The buffer must be big enough to hold the result plus one terminating null 16 | // character. 17 | // 18 | // The produced digits might be too short in which case the caller has to fill 19 | // the gaps with '0's. 20 | // Example: FastFixedDtoa(0.001, 5, ...) is allowed to return buffer = "1", and 21 | // decimal_point = -2. 22 | // Halfway cases are rounded towards +/-Infinity (away from 0). The call 23 | // FastFixedDtoa(0.15, 2, ...) thus returns buffer = "2", decimal_point = 0. 24 | // The returned buffer may contain digits that would be truncated from the 25 | // shortest representation of the input. 26 | // 27 | // This method only works for some parameters. If it can't handle the input it 28 | // returns false. The output is null-terminated when the function succeeds. 29 | V8_BASE_EXPORT bool FastFixedDtoa(double v, int fractional_count, 30 | Vector buffer, int* length, 31 | int* decimal_point); 32 | 33 | } // namespace base 34 | } // namespace v8 35 | 36 | #endif // V8_BASE_NUMBERS_FIXED_DTOA_H_ 37 | -------------------------------------------------------------------------------- /src/base/numbers/strtod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 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_BASE_NUMBERS_STRTOD_H_ 6 | #define V8_BASE_NUMBERS_STRTOD_H_ 7 | 8 | #include "src/base/vector.h" 9 | 10 | namespace v8 { 11 | namespace base { 12 | 13 | // The buffer must only contain digits in the range [0-9]. It must not 14 | // contain a dot or a sign. It must not start with '0', and must not be empty. 15 | V8_BASE_EXPORT double Strtod(Vector buffer, int exponent); 16 | 17 | } // namespace base 18 | } // namespace v8 19 | 20 | #endif // V8_BASE_NUMBERS_STRTOD_H_ 21 | -------------------------------------------------------------------------------- /src/base/once.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2012 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 | #include "src/base/once.h" 6 | 7 | #ifdef _WIN32 8 | #include 9 | #elif defined(V8_OS_STARBOARD) 10 | #include "starboard/thread.h" 11 | #else 12 | #include 13 | #endif 14 | 15 | namespace v8 { 16 | namespace base { 17 | 18 | void CallOnceImpl(OnceType* once, std::function init_func) { 19 | // Fast path. The provided function was already executed. 20 | if (once->load(std::memory_order_acquire) == ONCE_STATE_DONE) { 21 | return; 22 | } 23 | 24 | // The function execution did not complete yet. The once object can be in one 25 | // of the two following states: 26 | // - UNINITIALIZED: We are the first thread calling this function. 27 | // - EXECUTING_FUNCTION: Another thread is already executing the function. 28 | // 29 | // First, try to change the state from UNINITIALIZED to EXECUTING_FUNCTION 30 | // atomically. 31 | uint8_t expected = ONCE_STATE_UNINITIALIZED; 32 | if (once->compare_exchange_strong(expected, ONCE_STATE_EXECUTING_FUNCTION, 33 | std::memory_order_acq_rel)) { 34 | // We are the first thread to call this function, so we have to call the 35 | // function. 36 | init_func(); 37 | once->store(ONCE_STATE_DONE, std::memory_order_release); 38 | } else { 39 | // Another thread has already started executing the function. We need to 40 | // wait until it completes the initialization. 41 | while (once->load(std::memory_order_acquire) == 42 | ONCE_STATE_EXECUTING_FUNCTION) { 43 | #ifdef _WIN32 44 | ::Sleep(0); 45 | #elif defined(V8_OS_STARBOARD) 46 | SbThreadYield(); 47 | #else 48 | sched_yield(); 49 | #endif 50 | } 51 | } 52 | } 53 | 54 | } // namespace base 55 | } // namespace v8 56 | -------------------------------------------------------------------------------- /src/base/page-allocator.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_BASE_PAGE_ALLOCATOR_H_ 6 | #define V8_BASE_PAGE_ALLOCATOR_H_ 7 | 8 | #include 9 | 10 | #include "include/v8-platform.h" 11 | #include "src/base/base-export.h" 12 | #include "src/base/compiler-specific.h" 13 | 14 | namespace v8 { 15 | namespace base { 16 | 17 | class SharedMemory; 18 | 19 | class V8_BASE_EXPORT PageAllocator 20 | : public NON_EXPORTED_BASE(::v8::PageAllocator) { 21 | public: 22 | PageAllocator(); 23 | ~PageAllocator() override = default; 24 | 25 | size_t AllocatePageSize() override { return allocate_page_size_; } 26 | 27 | size_t CommitPageSize() override { return commit_page_size_; } 28 | 29 | void SetRandomMmapSeed(int64_t seed) override; 30 | 31 | void* GetRandomMmapAddr() override; 32 | 33 | void* AllocatePages(void* hint, size_t size, size_t alignment, 34 | PageAllocator::Permission access) override; 35 | 36 | bool CanAllocateSharedPages() override; 37 | 38 | std::unique_ptr AllocateSharedPages( 39 | size_t size, const void* original_address) override; 40 | 41 | bool FreePages(void* address, size_t size) override; 42 | 43 | bool ReleasePages(void* address, size_t size, size_t new_size) override; 44 | 45 | bool SetPermissions(void* address, size_t size, 46 | PageAllocator::Permission access) override; 47 | 48 | bool RecommitPages(void* address, size_t size, 49 | PageAllocator::Permission access) override; 50 | 51 | bool DiscardSystemPages(void* address, size_t size) override; 52 | 53 | bool DecommitPages(void* address, size_t size) override; 54 | 55 | private: 56 | friend class v8::base::SharedMemory; 57 | 58 | void* RemapShared(void* old_address, void* new_address, size_t size); 59 | 60 | const size_t allocate_page_size_; 61 | const size_t commit_page_size_; 62 | }; 63 | 64 | } // namespace base 65 | } // namespace v8 66 | #endif // V8_BASE_PAGE_ALLOCATOR_H_ 67 | -------------------------------------------------------------------------------- /src/base/platform/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" 11 | } -------------------------------------------------------------------------------- /src/base/platform/OWNERS: -------------------------------------------------------------------------------- 1 | hpayer@chromium.org 2 | mlippautz@chromium.org 3 | victorgomes@chromium.org 4 | 5 | per-file platform-fuchsia.cc=wez@chromium.org 6 | -------------------------------------------------------------------------------- /src/base/platform/platform-linux.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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_BASE_PLATFORM_PLATFORM_LINUX_H_ 6 | #define V8_BASE_PLATFORM_PLATFORM_LINUX_H_ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "src/base/base-export.h" 14 | #include "src/base/optional.h" 15 | #include "src/base/platform/platform.h" 16 | 17 | namespace v8 { 18 | namespace base { 19 | 20 | // Represents a memory region, as parsed from /proc/PID/maps. 21 | // Visible for testing. 22 | struct V8_BASE_EXPORT MemoryRegion { 23 | uintptr_t start; 24 | uintptr_t end; 25 | char permissions[5]; 26 | off_t offset; 27 | dev_t dev; 28 | ino_t inode; 29 | std::string pathname; 30 | 31 | // |line| must not contains the tail '\n'. 32 | static base::Optional FromMapsLine(const char* line); 33 | }; 34 | 35 | // The |fp| parameter is for testing, to pass a fake /proc/self/maps file. 36 | V8_BASE_EXPORT std::vector GetSharedLibraryAddresses( 37 | FILE* fp); 38 | 39 | } // namespace base 40 | } // namespace v8 41 | 42 | #endif // V8_BASE_PLATFORM_PLATFORM_LINUX_H_ 43 | -------------------------------------------------------------------------------- /src/base/platform/platform-posix-time.cc: -------------------------------------------------------------------------------- 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 | #include 6 | 7 | #include "src/base/platform/platform-posix-time.h" 8 | 9 | namespace v8 { 10 | namespace base { 11 | 12 | const char* PosixDefaultTimezoneCache::LocalTimezone(double time) { 13 | if (std::isnan(time)) return ""; 14 | time_t tv = static_cast(std::floor(time / msPerSecond)); 15 | struct tm tm; 16 | struct tm* t = localtime_r(&tv, &tm); 17 | if (!t || !t->tm_zone) return ""; 18 | return t->tm_zone; 19 | } 20 | 21 | double PosixDefaultTimezoneCache::LocalTimeOffset(double time_ms, bool is_utc) { 22 | // Preserve the old behavior for non-ICU implementation by ignoring both 23 | // time_ms and is_utc. 24 | time_t tv = time(nullptr); 25 | struct tm tm; 26 | struct tm* t = localtime_r(&tv, &tm); 27 | // tm_gmtoff includes any daylight savings offset, so subtract it. 28 | return static_cast(t->tm_gmtoff * msPerSecond - 29 | (t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); 30 | } 31 | 32 | } // namespace base 33 | } // namespace v8 34 | -------------------------------------------------------------------------------- /src/base/platform/platform-posix-time.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_BASE_PLATFORM_PLATFORM_POSIX_TIME_H_ 6 | #define V8_BASE_PLATFORM_PLATFORM_POSIX_TIME_H_ 7 | 8 | #include "src/base/platform/platform-posix.h" 9 | 10 | namespace v8 { 11 | namespace base { 12 | 13 | class PosixDefaultTimezoneCache : public PosixTimezoneCache { 14 | public: 15 | const char* LocalTimezone(double time_ms) override; 16 | double LocalTimeOffset(double time_ms, bool is_utc) override; 17 | 18 | ~PosixDefaultTimezoneCache() override = default; 19 | }; 20 | 21 | } // namespace base 22 | } // namespace v8 23 | 24 | #endif // V8_BASE_PLATFORM_PLATFORM_POSIX_TIME_H_ 25 | -------------------------------------------------------------------------------- /src/base/platform/platform-posix.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_BASE_PLATFORM_PLATFORM_POSIX_H_ 6 | #define V8_BASE_PLATFORM_PLATFORM_POSIX_H_ 7 | 8 | #include "include/v8config.h" 9 | #include "src/base/platform/platform.h" 10 | #include "src/base/timezone-cache.h" 11 | 12 | namespace v8 { 13 | namespace base { 14 | 15 | void PosixInitializeCommon(bool hard_abort, const char* const gc_fake_mmap); 16 | 17 | class PosixTimezoneCache : public TimezoneCache { 18 | public: 19 | double DaylightSavingsOffset(double time_ms) override; 20 | void Clear(TimeZoneDetection) override {} 21 | ~PosixTimezoneCache() override = default; 22 | 23 | protected: 24 | static const int msPerSecond = 1000; 25 | }; 26 | 27 | #if !V8_OS_FUCHSIA 28 | int GetProtectionFromMemoryPermission(OS::MemoryPermission access); 29 | #endif 30 | 31 | } // namespace base 32 | } // namespace v8 33 | 34 | #endif // V8_BASE_PLATFORM_PLATFORM_POSIX_H_ 35 | -------------------------------------------------------------------------------- /src/base/platform/wrappers.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_BASE_PLATFORM_WRAPPERS_H_ 6 | #define V8_BASE_PLATFORM_WRAPPERS_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef V8_OS_STARBOARD 14 | #include "starboard/string.h" 15 | #endif 16 | 17 | namespace v8::base { 18 | 19 | inline char* Strdup(const char* source) { 20 | #if V8_OS_STARBOARD 21 | return SbStringDuplicate(source); 22 | #else 23 | return strdup(source); 24 | #endif 25 | } 26 | 27 | inline FILE* Fopen(const char* filename, const char* mode) { 28 | #if V8_OS_STARBOARD 29 | return NULL; 30 | #else 31 | return fopen(filename, mode); 32 | #endif 33 | } 34 | 35 | inline int Fclose(FILE* stream) { 36 | #if V8_OS_STARBOARD 37 | return -1; 38 | #else 39 | return fclose(stream); 40 | #endif 41 | } 42 | 43 | } // namespace v8::base 44 | 45 | #endif // V8_BASE_PLATFORM_WRAPPERS_H_ 46 | -------------------------------------------------------------------------------- /src/base/qnx-math.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_BASE_QNX_MATH_H_ 6 | #define V8_BASE_QNX_MATH_H_ 7 | 8 | #include 9 | 10 | #undef fpclassify 11 | #undef isfinite 12 | #undef isinf 13 | #undef isnan 14 | #undef isnormal 15 | #undef signbit 16 | 17 | using std::lrint; 18 | 19 | #endif // V8_BASE_QNX_MATH_H_ 20 | -------------------------------------------------------------------------------- /src/base/ring-buffer.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_BASE_RING_BUFFER_H_ 6 | #define V8_BASE_RING_BUFFER_H_ 7 | 8 | #include "src/base/macros.h" 9 | 10 | namespace v8 { 11 | namespace base { 12 | 13 | template 14 | class RingBuffer { 15 | public: 16 | RingBuffer() { Reset(); } 17 | RingBuffer(const RingBuffer&) = delete; 18 | RingBuffer& operator=(const RingBuffer&) = delete; 19 | 20 | static const int kSize = 10; 21 | 22 | void Push(const T& value) { 23 | if (count_ == kSize) { 24 | elements_[start_++] = value; 25 | if (start_ == kSize) start_ = 0; 26 | } else { 27 | DCHECK_EQ(start_, 0); 28 | elements_[count_++] = value; 29 | } 30 | } 31 | 32 | int Count() const { return count_; } 33 | 34 | template 35 | T Sum(Callback callback, const T& initial) const { 36 | int j = start_ + count_ - 1; 37 | if (j >= kSize) j -= kSize; 38 | T result = initial; 39 | for (int i = 0; i < count_; i++) { 40 | result = callback(result, elements_[j]); 41 | if (--j == -1) j += kSize; 42 | } 43 | return result; 44 | } 45 | 46 | void Reset() { start_ = count_ = 0; } 47 | 48 | private: 49 | T elements_[kSize]; 50 | int start_; 51 | int count_; 52 | }; 53 | 54 | } // namespace base 55 | } // namespace v8 56 | 57 | #endif // V8_BASE_RING_BUFFER_H_ 58 | -------------------------------------------------------------------------------- /src/base/safe_conversions_arm_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // Slightly adapted for inclusion in V8. 6 | // Copyright 2014 the V8 project authors. All rights reserved. 7 | // List of adaptations: 8 | // - include guard names 9 | // - wrap in v8 namespace 10 | // - include paths 11 | 12 | #ifndef V8_BASE_SAFE_CONVERSIONS_ARM_IMPL_H_ 13 | #define V8_BASE_SAFE_CONVERSIONS_ARM_IMPL_H_ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "src/base/safe_conversions_impl.h" 20 | 21 | namespace v8 { 22 | namespace base { 23 | namespace internal { 24 | 25 | // Fast saturation to a destination type. 26 | template 27 | struct SaturateFastAsmOp { 28 | static constexpr bool is_supported = 29 | std::is_signed::value && std::is_integral::value && 30 | std::is_integral::value && 31 | IntegerBitsPlusSign::value <= IntegerBitsPlusSign::value && 32 | IntegerBitsPlusSign::value <= IntegerBitsPlusSign::value && 33 | !IsTypeInRangeForNumericType::value; 34 | 35 | __attribute__((always_inline)) static Dst Do(Src value) { 36 | int32_t src = value; 37 | typename std::conditional::value, int32_t, 38 | uint32_t>::type result; 39 | if (std::is_signed::value) { 40 | asm("ssat %[dst], %[shift], %[src]" 41 | : [dst] "=r"(result) 42 | : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign::value <= 32 43 | ? IntegerBitsPlusSign::value 44 | : 32)); 45 | } else { 46 | asm("usat %[dst], %[shift], %[src]" 47 | : [dst] "=r"(result) 48 | : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign::value < 32 49 | ? IntegerBitsPlusSign::value 50 | : 31)); 51 | } 52 | return static_cast(result); 53 | } 54 | }; 55 | 56 | } // namespace internal 57 | } // namespace base 58 | } // namespace v8 59 | 60 | #endif // V8_BASE_SAFE_CONVERSIONS_ARM_IMPL_H_ 61 | -------------------------------------------------------------------------------- /src/base/sanitizer/asan.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 | // AddressSanitizer support. 6 | 7 | #ifndef V8_BASE_SANITIZER_ASAN_H_ 8 | #define V8_BASE_SANITIZER_ASAN_H_ 9 | 10 | #include 11 | 12 | #include "src/base/macros.h" 13 | 14 | #ifdef V8_USE_ADDRESS_SANITIZER 15 | 16 | #include 17 | 18 | #if !defined(ASAN_POISON_MEMORY_REGION) || !defined(ASAN_UNPOISON_MEMORY_REGION) 19 | #error \ 20 | "ASAN_POISON_MEMORY_REGION and ASAN_UNPOISON_MEMORY_REGION must be defined" 21 | #endif 22 | 23 | #define DISABLE_ASAN __attribute__((no_sanitize_address)) 24 | 25 | // Check that all bytes in a memory region are poisoned. This is different from 26 | // `__asan_region_is_poisoned()` which only requires a single byte in the region 27 | // to be poisoned. Please note that the macro only works if both start and size 28 | // are multiple of asan's shadow memory granularity. 29 | #define ASAN_CHECK_WHOLE_MEMORY_REGION_IS_POISONED(start, size) \ 30 | do { \ 31 | for (size_t i = 0; i < size; i++) { \ 32 | CHECK(__asan_address_is_poisoned(reinterpret_cast(start) + \ 33 | i)); \ 34 | } \ 35 | } while (0) 36 | 37 | #else // !V8_USE_ADDRESS_SANITIZER 38 | 39 | #define DISABLE_ASAN 40 | 41 | #define ASAN_POISON_MEMORY_REGION(start, size) \ 42 | static_assert(std::is_pointer::value, \ 43 | "static type violation"); \ 44 | static_assert(std::is_convertible::value, \ 45 | "static type violation"); \ 46 | USE(start, size) 47 | 48 | #define ASAN_UNPOISON_MEMORY_REGION(start, size) \ 49 | ASAN_POISON_MEMORY_REGION(start, size) 50 | 51 | #define ASAN_CHECK_WHOLE_MEMORY_REGION_IS_POISONED(start, size) \ 52 | ASAN_POISON_MEMORY_REGION(start, size) 53 | 54 | #endif // !V8_USE_ADDRESS_SANITIZER 55 | 56 | #endif // V8_BASE_SANITIZER_ASAN_H_ 57 | -------------------------------------------------------------------------------- /src/base/sanitizer/lsan-page-allocator.cc: -------------------------------------------------------------------------------- 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 | #include "src/base/sanitizer/lsan-page-allocator.h" 6 | 7 | #include "include/v8-platform.h" 8 | #include "src/base/logging.h" 9 | 10 | #if defined(LEAK_SANITIZER) 11 | #include 12 | #endif 13 | 14 | namespace v8 { 15 | namespace base { 16 | 17 | LsanPageAllocator::LsanPageAllocator(v8::PageAllocator* page_allocator) 18 | : page_allocator_(page_allocator), 19 | allocate_page_size_(page_allocator_->AllocatePageSize()), 20 | commit_page_size_(page_allocator_->CommitPageSize()) { 21 | DCHECK_NOT_NULL(page_allocator); 22 | } 23 | 24 | void* LsanPageAllocator::AllocatePages(void* hint, size_t size, 25 | size_t alignment, 26 | PageAllocator::Permission access) { 27 | void* result = page_allocator_->AllocatePages(hint, size, alignment, access); 28 | #if defined(LEAK_SANITIZER) 29 | if (result != nullptr) { 30 | __lsan_register_root_region(result, size); 31 | } 32 | #endif 33 | return result; 34 | } 35 | 36 | std::unique_ptr 37 | LsanPageAllocator::AllocateSharedPages(size_t size, 38 | const void* original_address) { 39 | auto result = page_allocator_->AllocateSharedPages(size, original_address); 40 | #if defined(LEAK_SANITIZER) 41 | if (result != nullptr) { 42 | __lsan_register_root_region(result->GetMemory(), size); 43 | } 44 | #endif 45 | return result; 46 | } 47 | 48 | bool LsanPageAllocator::CanAllocateSharedPages() { 49 | return page_allocator_->CanAllocateSharedPages(); 50 | } 51 | 52 | bool LsanPageAllocator::FreePages(void* address, size_t size) { 53 | CHECK(page_allocator_->FreePages(address, size)); 54 | #if defined(LEAK_SANITIZER) 55 | __lsan_unregister_root_region(address, size); 56 | #endif 57 | return true; 58 | } 59 | 60 | bool LsanPageAllocator::ReleasePages(void* address, size_t size, 61 | size_t new_size) { 62 | CHECK(page_allocator_->ReleasePages(address, size, new_size)); 63 | #if defined(LEAK_SANITIZER) 64 | __lsan_unregister_root_region(address, size); 65 | __lsan_register_root_region(address, new_size); 66 | #endif 67 | return true; 68 | } 69 | 70 | } // namespace base 71 | } // namespace v8 72 | -------------------------------------------------------------------------------- /src/base/sanitizer/lsan.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | // LeakSanitizer support. 6 | 7 | #ifndef V8_BASE_SANITIZER_LSAN_H_ 8 | #define V8_BASE_SANITIZER_LSAN_H_ 9 | 10 | #include 11 | 12 | #include "src/base/macros.h" 13 | 14 | // There is no compile time flag for LSan, so enable this whenever ASan is 15 | // enabled. Note that LSan can be used as part of ASan with 'detect_leaks=1'. 16 | // On Windows, LSan is not implemented yet, so disable it there. 17 | #if defined(V8_USE_ADDRESS_SANITIZER) && !defined(V8_OS_WIN) 18 | 19 | #include 20 | 21 | #define LSAN_IGNORE_OBJECT(ptr) __lsan_ignore_object(ptr) 22 | 23 | #else // defined(V8_USE_ADDRESS_SANITIZER) && !defined(V8_OS_WIN) 24 | 25 | #define LSAN_IGNORE_OBJECT(ptr) \ 26 | static_assert(std::is_convertible::value, \ 27 | "LSAN_IGNORE_OBJECT can only be used with pointer types") 28 | 29 | #endif // defined(V8_USE_ADDRESS_SANITIZER) && !defined(V8_OS_WIN) 30 | 31 | #endif // V8_BASE_SANITIZER_LSAN_H_ 32 | -------------------------------------------------------------------------------- /src/base/sanitizer/msan.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // MemorySanitizer support. 6 | 7 | #ifndef V8_BASE_SANITIZER_MSAN_H_ 8 | #define V8_BASE_SANITIZER_MSAN_H_ 9 | 10 | #include "src/base/macros.h" 11 | #include "src/base/memory.h" 12 | 13 | #ifdef V8_USE_MEMORY_SANITIZER 14 | 15 | #include 16 | 17 | // Marks a memory range as uninitialized, as if it was allocated here. 18 | #define MSAN_ALLOCATED_UNINITIALIZED_MEMORY(start, size) \ 19 | __msan_allocated_memory(reinterpret_cast(start), (size)) 20 | 21 | // Marks a memory range as initialized. 22 | #define MSAN_MEMORY_IS_INITIALIZED(start, size) \ 23 | __msan_unpoison(reinterpret_cast(start), (size)) 24 | 25 | #else // !V8_USE_MEMORY_SANITIZER 26 | 27 | #define MSAN_ALLOCATED_UNINITIALIZED_MEMORY(start, size) \ 28 | static_assert((std::is_pointer::value || \ 29 | std::is_same::value), \ 30 | "static type violation"); \ 31 | static_assert(std::is_convertible::value, \ 32 | "static type violation"); \ 33 | USE(start, size) 34 | 35 | #define MSAN_MEMORY_IS_INITIALIZED(start, size) \ 36 | MSAN_ALLOCATED_UNINITIALIZED_MEMORY(start, size) 37 | 38 | #endif // V8_USE_MEMORY_SANITIZER 39 | 40 | #endif // V8_BASE_SANITIZER_MSAN_H_ 41 | -------------------------------------------------------------------------------- /src/base/sanitizer/tsan.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 | // ThreadSanitizer support. 6 | 7 | #ifndef V8_BASE_SANITIZER_TSAN_H_ 8 | #define V8_BASE_SANITIZER_TSAN_H_ 9 | 10 | #if defined(THREAD_SANITIZER) 11 | 12 | #define DISABLE_TSAN __attribute__((no_sanitize_thread)) 13 | 14 | #else // !defined(THREAD_SANITIZER) 15 | 16 | #define DISABLE_TSAN 17 | 18 | #endif // !defined(THREAD_SANITIZER) 19 | 20 | #endif // V8_BASE_SANITIZER_TSAN_H_ 21 | -------------------------------------------------------------------------------- /src/base/strings.cc: -------------------------------------------------------------------------------- 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 | #include "src/base/strings.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "src/base/platform/platform.h" 12 | 13 | namespace v8 { 14 | namespace base { 15 | 16 | int VSNPrintF(Vector str, const char* format, va_list args) { 17 | return OS::VSNPrintF(str.begin(), str.length(), format, args); 18 | } 19 | 20 | int SNPrintF(Vector str, const char* format, ...) { 21 | va_list args; 22 | va_start(args, format); 23 | int result = VSNPrintF(str, format, args); 24 | va_end(args); 25 | return result; 26 | } 27 | 28 | void StrNCpy(base::Vector dest, const char* src, size_t n) { 29 | base::OS::StrNCpy(dest.begin(), dest.length(), src, n); 30 | } 31 | 32 | } // namespace base 33 | } // namespace v8 34 | -------------------------------------------------------------------------------- /src/base/strings.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 V8_BASE_STRINGS_H_ 6 | #define V8_BASE_STRINGS_H_ 7 | 8 | #include "src/base/base-export.h" 9 | #include "src/base/macros.h" 10 | #include "src/base/vector.h" 11 | 12 | namespace v8 { 13 | namespace base { 14 | 15 | // Latin1/UTF-16 constants 16 | // Code-point values in Unicode 4.0 are 21 bits wide. 17 | // Code units in UTF-16 are 16 bits wide. 18 | using uc16 = uint16_t; 19 | using uc32 = uint32_t; 20 | constexpr int kUC16Size = sizeof(uc16); 21 | 22 | V8_BASE_EXPORT int PRINTF_FORMAT(2, 0) 23 | VSNPrintF(Vector str, const char* format, va_list args); 24 | 25 | // Safe formatting print. Ensures that str is always null-terminated. 26 | // Returns the number of chars written, or -1 if output was truncated. 27 | V8_BASE_EXPORT int PRINTF_FORMAT(2, 3) 28 | SNPrintF(Vector str, const char* format, ...); 29 | 30 | V8_BASE_EXPORT void StrNCpy(base::Vector dest, const char* src, size_t n); 31 | 32 | // Returns the value (0 .. 15) of a hexadecimal character c. 33 | // If c is not a legal hexadecimal character, returns a value < 0. 34 | inline int HexValue(uc32 c) { 35 | c -= '0'; 36 | if (static_cast(c) <= 9) return c; 37 | c = (c | 0x20) - ('a' - '0'); // detect 0x11..0x16 and 0x31..0x36. 38 | if (static_cast(c) <= 5) return c + 10; 39 | return -1; 40 | } 41 | 42 | inline char HexCharOfValue(int value) { 43 | DCHECK(0 <= value && value <= 16); 44 | if (value < 10) return value + '0'; 45 | return value - 10 + 'A'; 46 | } 47 | 48 | } // namespace base 49 | } // namespace v8 50 | 51 | #endif // V8_BASE_STRINGS_H_ 52 | -------------------------------------------------------------------------------- /src/base/sys-info.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_BASE_SYS_INFO_H_ 6 | #define V8_BASE_SYS_INFO_H_ 7 | 8 | #include 9 | 10 | #include "src/base/base-export.h" 11 | #include "src/base/compiler-specific.h" 12 | 13 | namespace v8 { 14 | namespace base { 15 | 16 | class V8_BASE_EXPORT SysInfo final { 17 | public: 18 | // Returns the number of logical processors/core on the current machine. 19 | static int NumberOfProcessors(); 20 | 21 | // Returns the number of bytes of physical memory on the current machine. 22 | static int64_t AmountOfPhysicalMemory(); 23 | 24 | // Returns the number of bytes of virtual memory of this process. A return 25 | // value of zero means that there is no limit on the available virtual memory. 26 | static int64_t AmountOfVirtualMemory(); 27 | }; 28 | 29 | } // namespace base 30 | } // namespace v8 31 | 32 | #endif // V8_BASE_SYS_INFO_H_ 33 | -------------------------------------------------------------------------------- /src/base/timezone-cache.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_BASE_TIMEZONE_CACHE_H_ 6 | #define V8_BASE_TIMEZONE_CACHE_H_ 7 | 8 | namespace v8 { 9 | namespace base { 10 | 11 | class TimezoneCache { 12 | public: 13 | // Short name of the local timezone (e.g., EST) 14 | virtual const char* LocalTimezone(double time_ms) = 0; 15 | 16 | // ES #sec-daylight-saving-time-adjustment 17 | // Daylight Saving Time Adjustment 18 | virtual double DaylightSavingsOffset(double time_ms) = 0; 19 | 20 | // ES #sec-local-time-zone-adjustment 21 | // Local Time Zone Adjustment 22 | // 23 | // https://github.com/tc39/ecma262/pull/778 24 | virtual double LocalTimeOffset(double time_ms, bool is_utc) = 0; 25 | 26 | /** 27 | * Time zone redetection indicator for Clear function. 28 | * 29 | * kSkip indicates host time zone doesn't have to be redetected. 30 | * kRedetect indicates host time zone should be redetected, and used to set 31 | * the default time zone. 32 | * 33 | * The host time zone detection may require file system access or similar 34 | * operations unlikely to be available inside a sandbox. If v8 is run inside a 35 | * sandbox, the host time zone has to be detected outside the sandbox 36 | * separately. 37 | */ 38 | enum class TimeZoneDetection { kSkip, kRedetect }; 39 | 40 | // Called when the local timezone changes 41 | virtual void Clear(TimeZoneDetection time_zone_detection) = 0; 42 | 43 | // Called when tearing down the isolate 44 | virtual ~TimezoneCache() = default; 45 | }; 46 | 47 | } // namespace base 48 | } // namespace v8 49 | 50 | #endif // V8_BASE_TIMEZONE_CACHE_H_ 51 | -------------------------------------------------------------------------------- /src/base/ubsan.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | #include 6 | #include 7 | 8 | #include "src/base/build_config.h" 9 | 10 | #if !defined(UNDEFINED_SANITIZER) || !defined(V8_TARGET_ARCH_32_BIT) 11 | #error "This file is only needed for 32-bit UBSan builds." 12 | #endif 13 | 14 | // Compiling with -fsanitize=undefined on 32-bit platforms requires __mulodi4 15 | // to be available. Usually it comes from libcompiler_rt, which our build 16 | // doesn't provide, so here is a custom implementation (inspired by digit_mul 17 | // in src/objects/bigint.cc). 18 | extern "C" int64_t __mulodi4(int64_t a, int64_t b, int* overflow) { 19 | // Multiply in 32-bit chunks. 20 | // For inputs [AH AL]*[BH BL], the result is: 21 | // 22 | // [AL*BL] // r_low 23 | // + [AL*BH] // r_mid1 24 | // + [AH*BL] // r_mid2 25 | // + [AH*BH] // r_high 26 | // = [R4 R3 R2 R1] // high = [R4 R3], low = [R2 R1] 27 | // 28 | // Where of course we must be careful with carries between the columns. 29 | uint64_t a_low = a & 0xFFFFFFFFu; 30 | uint64_t a_high = static_cast(a) >> 32; 31 | uint64_t b_low = b & 0xFFFFFFFFu; 32 | uint64_t b_high = static_cast(b) >> 32; 33 | 34 | uint64_t r_low = a_low * b_low; 35 | uint64_t r_mid1 = a_low * b_high; 36 | uint64_t r_mid2 = a_high * b_low; 37 | uint64_t r_high = a_high * b_high; 38 | 39 | uint64_t result1 = r_low + (r_mid1 << 32); 40 | if (result1 < r_low) r_high++; 41 | uint64_t result2 = result1 + (r_mid2 << 32); 42 | if (result2 < result1) r_high++; 43 | r_high += (r_mid1 >> 32) + (r_mid2 >> 32); 44 | int64_t result = static_cast(result2); 45 | uint64_t result_sign = (result >> 63); 46 | uint64_t expected_result_sign = (a >> 63) ^ (b >> 63); 47 | 48 | *overflow = (r_high > 0 || result_sign != expected_result_sign) ? 1 : 0; 49 | return result; 50 | } 51 | -------------------------------------------------------------------------------- /src/base/v8-fallthrough.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_BASE_V8_FALLTHROUGH_H_ 6 | #define V8_BASE_V8_FALLTHROUGH_H_ 7 | 8 | // When clang suggests inserting [[clang::fallthrough]], it first checks if 9 | // it knows of a macro expanding to it, and if so suggests inserting the 10 | // macro. This means that this macro must be used only in code internal 11 | // to v8, so that v8's user code doesn't end up getting suggestions 12 | // for V8_FALLTHROUGH instead of the user-specific fallthrough macro. 13 | // So do not include this header in any of v8's public headers -- only 14 | // use it in src/, not in include/. 15 | #if defined(__clang__) 16 | #define V8_FALLTHROUGH [[clang::fallthrough]] 17 | #else 18 | #define V8_FALLTHROUGH 19 | #endif 20 | 21 | #endif // V8_BASE_V8_FALLTHROUGH_H_ 22 | -------------------------------------------------------------------------------- /src/base/vlq-base64.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | #include 6 | #include 7 | 8 | #include "src/base/logging.h" 9 | #include "src/base/vlq-base64.h" 10 | 11 | namespace v8 { 12 | namespace base { 13 | 14 | namespace { 15 | constexpr int8_t kCharToDigit[] = { 16 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19 | -1, -1, -1, -1, -1, -1, -1, 0x3e, -1, -1, -1, 0x3f, 20 | 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, -1, -1, 21 | -1, -1, -1, -1, -1, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 22 | 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 23 | 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, -1, -1, -1, -1, -1, 24 | -1, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 25 | 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 26 | 0x31, 0x32, 0x33, -1, -1, -1, -1, -1}; 27 | 28 | constexpr uint32_t kContinueShift = 5; 29 | constexpr uint32_t kContinueMask = 1 << kContinueShift; 30 | constexpr uint32_t kDataMask = kContinueMask - 1; 31 | 32 | int8_t charToDigitDecode(uint8_t c) { return c < 128u ? kCharToDigit[c] : -1; } 33 | } // namespace 34 | 35 | int8_t charToDigitDecodeForTesting(uint8_t c) { return charToDigitDecode(c); } 36 | 37 | int32_t VLQBase64Decode(const char* start, size_t sz, size_t* pos) { 38 | uint32_t res = 0; 39 | uint64_t shift = 0; 40 | int32_t digit; 41 | 42 | do { 43 | if (*pos >= sz) { 44 | return std::numeric_limits::min(); 45 | } 46 | digit = static_cast(charToDigitDecode(start[*pos])); 47 | bool is_last_byte = (shift + kContinueShift >= 32); 48 | if (digit == -1 || (is_last_byte && (digit >> 2) != 0)) { 49 | return std::numeric_limits::min(); 50 | } 51 | res += (digit & kDataMask) << shift; 52 | shift += kContinueShift; 53 | (*pos)++; 54 | } while (digit & kContinueMask); 55 | return (res & 1) ? -static_cast(res >> 1) : (res >> 1); 56 | } 57 | } // namespace base 58 | } // namespace v8 59 | -------------------------------------------------------------------------------- /src/base/vlq-base64.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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_BASE_VLQ_BASE64_H_ 6 | #define V8_BASE_VLQ_BASE64_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "src/base/base-export.h" 12 | 13 | namespace v8 { 14 | namespace base { 15 | V8_BASE_EXPORT int8_t charToDigitDecodeForTesting(uint8_t c); 16 | 17 | // Decodes a VLQ-Base64-encoded string into 32bit digits. A valid return value 18 | // is within [-2^31+1, 2^31-1]. This function returns -2^31 19 | // (std::numeric_limits::min()) when bad input s is passed. 20 | V8_BASE_EXPORT int32_t VLQBase64Decode(const char* start, size_t sz, 21 | size_t* pos); 22 | } // namespace base 23 | } // namespace v8 24 | #endif // V8_BASE_VLQ_BASE64_H_ 25 | -------------------------------------------------------------------------------- /src/heap/base/active-system-pages.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | #include "src/heap/base/active-system-pages.h" 6 | 7 | #include 8 | 9 | #include "src/base/bits.h" 10 | #include "src/base/macros.h" 11 | 12 | namespace heap { 13 | namespace base { 14 | 15 | size_t ActiveSystemPages::Init(size_t header_size, size_t page_size_bits, 16 | size_t user_page_size) { 17 | #if DEBUG 18 | size_t page_size = 1 << page_size_bits; 19 | DCHECK_LE(RoundUp(user_page_size, page_size) >> page_size_bits, 20 | ActiveSystemPages::kMaxPages); 21 | #endif // DEBUG 22 | Clear(); 23 | return Add(0, header_size, page_size_bits); 24 | } 25 | 26 | size_t ActiveSystemPages::Add(uintptr_t start, uintptr_t end, 27 | size_t page_size_bits) { 28 | const size_t page_size = 1 << page_size_bits; 29 | 30 | DCHECK_LE(start, end); 31 | DCHECK_LE(end, kMaxPages * page_size); 32 | 33 | // Make sure we actually get the bitcount as argument. 34 | DCHECK_LT(page_size_bits, sizeof(uintptr_t) * CHAR_BIT); 35 | 36 | const uintptr_t start_page_bit = 37 | RoundDown(start, page_size) >> page_size_bits; 38 | const uintptr_t end_page_bit = RoundUp(end, page_size) >> page_size_bits; 39 | DCHECK_LE(start_page_bit, end_page_bit); 40 | 41 | const uintptr_t bits = end_page_bit - start_page_bit; 42 | DCHECK_LE(bits, kMaxPages); 43 | const bitset_t mask = bits == kMaxPages 44 | ? int64_t{-1} 45 | : ((uint64_t{1} << bits) - 1) << start_page_bit; 46 | const bitset_t added_pages = ~value_ & mask; 47 | value_ |= mask; 48 | return added_pages.count(); 49 | } 50 | 51 | size_t ActiveSystemPages::Reduce(ActiveSystemPages updated_value) { 52 | DCHECK_EQ(~value_ & updated_value.value_, 0); 53 | const bitset_t removed_pages(value_ & ~updated_value.value_); 54 | value_ = updated_value.value_; 55 | return removed_pages.count(); 56 | } 57 | 58 | size_t ActiveSystemPages::Clear() { 59 | const size_t removed_pages = value_.count(); 60 | value_ = 0; 61 | return removed_pages; 62 | } 63 | 64 | size_t ActiveSystemPages::Size(size_t page_size_bits) const { 65 | // Make sure we don't get the full page size as argument. 66 | DCHECK_LT(page_size_bits, sizeof(uintptr_t) * CHAR_BIT); 67 | return value_.count() * (size_t{1} << page_size_bits); 68 | } 69 | 70 | } // namespace base 71 | } // namespace heap 72 | -------------------------------------------------------------------------------- /src/heap/base/active-system-pages.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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_HEAP_BASE_ACTIVE_SYSTEM_PAGES_H_ 6 | #define V8_HEAP_BASE_ACTIVE_SYSTEM_PAGES_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "src/base/macros.h" 12 | 13 | namespace heap { 14 | namespace base { 15 | 16 | // Class implements a bitset of system pages on a heap page. 17 | class ActiveSystemPages final { 18 | public: 19 | // Defines the maximum number of system pages that can be tracked in one 20 | // instance. 21 | static constexpr size_t kMaxPages = 64; 22 | 23 | // Initializes the set of active pages to the system pages for the header. 24 | V8_EXPORT_PRIVATE size_t Init(size_t header_size, size_t page_size_bits, 25 | size_t user_page_size); 26 | 27 | // Adds the pages for this memory range. Returns the number of freshly added 28 | // pages. 29 | V8_EXPORT_PRIVATE size_t Add(size_t start, size_t end, size_t page_size_bits); 30 | 31 | // Replaces the current bitset with the given argument. The new bitset needs 32 | // to be a proper subset of the current pages, which means this operation 33 | // can't add pages. Returns the number of removed pages. 34 | V8_EXPORT_PRIVATE size_t Reduce(ActiveSystemPages updated_value); 35 | 36 | // Removes all pages. Returns the number of removed pages. 37 | V8_EXPORT_PRIVATE size_t Clear(); 38 | 39 | // Returns the memory used with the given page size. 40 | V8_EXPORT_PRIVATE size_t Size(size_t page_size_bits) const; 41 | 42 | private: 43 | using bitset_t = std::bitset; 44 | 45 | bitset_t value_; 46 | }; 47 | 48 | } // namespace base 49 | } // namespace heap 50 | 51 | #endif // V8_HEAP_BASE_ACTIVE_SYSTEM_PAGES_H_ 52 | -------------------------------------------------------------------------------- /src/heap/base/asm/arm/push_registers_asm.cc: -------------------------------------------------------------------------------- 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 | // Push all callee-saved registers to get them on the stack for conservative 6 | // stack scanning. 7 | // 8 | // See asm/x64/push_registers_clang.cc for why the function is not generated 9 | // using clang. 10 | // 11 | // Do not depend on V8_TARGET_OS_* defines as some embedders may override the 12 | // GN toolchain (e.g. ChromeOS) and not provide them. 13 | 14 | // We maintain 8-byte alignment at calls by pushing an additional 15 | // non-callee-saved register (r3). 16 | // 17 | // Calling convention source: 18 | // https://en.wikipedia.org/wiki/Calling_convention#ARM_(A32) 19 | // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4127.html 20 | asm(".globl PushAllRegistersAndIterateStack \n" 21 | ".type PushAllRegistersAndIterateStack, %function \n" 22 | ".hidden PushAllRegistersAndIterateStack \n" 23 | "PushAllRegistersAndIterateStack: \n" 24 | // Push all callee-saved registers and save return address. 25 | // Only {r4-r11} are callee-saved registers. Push r3 in addition to align 26 | // the stack back to 8 bytes. 27 | " push {r3-r11, lr} \n" 28 | // Pass 1st parameter (r0) unchanged (Stack*). 29 | // Pass 2nd parameter (r1) unchanged (StackVisitor*). 30 | // Save 3rd parameter (r2; IterateStackCallback). 31 | " mov r3, r2 \n" 32 | // Pass 3rd parameter as sp (stack pointer). 33 | " mov r2, sp \n" 34 | // Call the callback. 35 | " blx r3 \n" 36 | // Discard all the registers. 37 | " add sp, sp, #36 \n" 38 | // Pop lr into pc which returns and switches mode if needed. 39 | " pop {pc} \n"); 40 | -------------------------------------------------------------------------------- /src/heap/base/asm/arm64/push_registers_masm.S: -------------------------------------------------------------------------------- 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 | ; This file is exactly the same as push_registers_asm.cc, just formatted for 6 | ; the Microsoft Arm Assembler. 7 | 8 | AREA |.text|, CODE, ALIGN=4, READONLY 9 | EXPORT PushAllRegistersAndIterateStack 10 | PushAllRegistersAndIterateStack 11 | ; x19-x29 are callee-saved 12 | STP x19, x20, [sp, #-16]! 13 | STP x21, x22, [sp, #-16]! 14 | STP x23, x24, [sp, #-16]! 15 | STP x25, x26, [sp, #-16]! 16 | STP x27, x28, [sp, #-16]! 17 | STP fp, lr, [sp, #-16]! 18 | ; Maintain frame pointer 19 | MOV fp, sp 20 | ; Pass 1st parameter (x0) unchanged (Stack*). 21 | ; Pass 2nd parameter (x1) unchanged (StackVisitor*). 22 | ; Save 3rd parameter (x2; IterateStackCallback) 23 | MOV x7, x2 24 | ; Pass 3rd parameter as sp (stack pointer) 25 | MOV x2, sp 26 | BLR x7 27 | ; Load return address 28 | LDR lr, [sp, #8] 29 | ; Restore frame pointer and pop all callee-saved registers. 30 | LDR fp, [sp], #96 31 | RET 32 | END -------------------------------------------------------------------------------- /src/heap/base/asm/ia32/push_registers_masm.asm: -------------------------------------------------------------------------------- 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 | ;; MASM syntax 6 | ;; https://docs.microsoft.com/en-us/cpp/assembler/masm/microsoft-macro-assembler-reference?view=vs-2019 7 | 8 | .model flat, C 9 | 10 | public PushAllRegistersAndIterateStack 11 | 12 | .code 13 | PushAllRegistersAndIterateStack: 14 | ;; Push all callee-saved registers to get them on the stack for conservative 15 | ;; stack scanning. 16 | ;; 17 | ;; We maintain 16-byte alignment at calls. There is an 8-byte return address 18 | ;; on the stack and we push 72 bytes which maintains 16-byte stack alignment 19 | ;; at the call. 20 | ;; 21 | ;; The following assumes cdecl calling convention. 22 | ;; Source: https://docs.microsoft.com/en-us/cpp/cpp/cdecl?view=vs-2019 23 | ;; 24 | ;; [ IterateStackCallback ] 25 | ;; [ StackVisitor* ] 26 | ;; [ Stack* ] 27 | ;; [ ret ] 28 | push ebp 29 | mov ebp, esp 30 | push ebx 31 | push esi 32 | push edi 33 | ;; Save 3rd parameter (IterateStackCallback). 34 | mov ecx, [ esp + 28 ] 35 | ;; Pass 3rd parameter as esp (stack pointer). 36 | push esp 37 | ;; Pass 2nd parameter (StackVisitor*). 38 | push [ esp + 28 ] 39 | ;; Pass 1st parameter (Stack*). 40 | push [ esp + 28 ] 41 | call ecx 42 | ;; Pop the callee-saved registers. 43 | add esp, 24 44 | ;; Restore rbp as it was used as frame pointer. 45 | pop ebp 46 | ret 47 | 48 | end 49 | -------------------------------------------------------------------------------- /src/heap/base/asm/s390/push_registers_asm.cc: -------------------------------------------------------------------------------- 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 | // Push all callee-saved registers to get them on the stack for conservative 6 | // stack scanning. 7 | 8 | // See asm/x64/push_registers_clang.cc for why the function is not generated 9 | // using clang. 10 | 11 | // Do not depend on V8_TARGET_OS_* defines as some embedders may override the 12 | // GN toolchain (e.g. ChromeOS) and not provide them. 13 | 14 | // S390 ABI source: 15 | // http://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html 16 | asm(".globl PushAllRegistersAndIterateStack \n" 17 | ".type PushAllRegistersAndIterateStack, %function \n" 18 | ".hidden PushAllRegistersAndIterateStack \n" 19 | "PushAllRegistersAndIterateStack: \n" 20 | // Push all callee-saved registers. 21 | // r6-r13, r14 and sp(r15) 22 | " stmg %r6, %sp, 48(%sp) \n" 23 | // Allocate frame. 24 | " lay %sp, -160(%sp) \n" 25 | // Pass 1st parameter (r2) unchanged (Stack*). 26 | // Pass 2nd parameter (r3) unchanged (StackVisitor*). 27 | // Save 3rd parameter (r4; IterateStackCallback). 28 | " lgr %r5, %r4 \n" 29 | // Pass sp as 3rd parameter. 160+48 to point 30 | // to callee saved region stored above. 31 | " lay %r4, 208(%sp) \n" 32 | // Call the callback. 33 | " basr %r14, %r5 \n" 34 | " lmg %r14,%sp, 272(%sp) \n" 35 | " br %r14 \n"); 36 | -------------------------------------------------------------------------------- /src/heap/base/asm/x64/push_registers_masm.asm: -------------------------------------------------------------------------------- 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 | ;; MASM syntax 6 | ;; https://docs.microsoft.com/en-us/cpp/assembler/masm/microsoft-macro-assembler-reference?view=vs-2019 7 | 8 | public PushAllRegistersAndIterateStack 9 | 10 | .code 11 | PushAllRegistersAndIterateStack: 12 | ;; Push all callee-saved registers to get them on the stack for conservative 13 | ;; stack scanning. 14 | ;; 15 | ;; We maintain 16-byte alignment at calls. There is an 8-byte return address 16 | ;; on the stack and we push 232 bytes which maintains 16-byte stack 17 | ;; alignment at the call. 18 | ;; Source: https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention 19 | ;; 20 | ;; rbp is callee-saved. Maintain proper frame pointer for debugging. 21 | push rbp 22 | mov rbp, rsp 23 | push 0CDCDCDh ;; Dummy for alignment. 24 | push rsi 25 | push rdi 26 | push rbx 27 | push r12 28 | push r13 29 | push r14 30 | push r15 31 | sub rsp, 160 32 | ;; Use aligned instrs as we are certain that the stack is properly aligned. 33 | movdqa xmmword ptr [rsp + 144], xmm6 34 | movdqa xmmword ptr [rsp + 128], xmm7 35 | movdqa xmmword ptr [rsp + 112], xmm8 36 | movdqa xmmword ptr [rsp + 96], xmm9 37 | movdqa xmmword ptr [rsp + 80], xmm10 38 | movdqa xmmword ptr [rsp + 64], xmm11 39 | movdqa xmmword ptr [rsp + 48], xmm12 40 | movdqa xmmword ptr [rsp + 32], xmm13 41 | movdqa xmmword ptr [rsp + 16], xmm14 42 | movdqa xmmword ptr [rsp], xmm15 43 | ;; Pass 1st parameter (rcx) unchanged (Stack*). 44 | ;; Pass 2nd parameter (rdx) unchanged (StackVisitor*). 45 | ;; Save 3rd parameter (r8; IterateStackCallback) 46 | mov r9, r8 47 | ;; Pass 3rd parameter as rsp (stack pointer). 48 | mov r8, rsp 49 | ;; Call the callback. 50 | call r9 51 | ;; Pop the callee-saved registers. 52 | add rsp, 224 53 | ;; Restore rbp as it was used as frame pointer. 54 | pop rbp 55 | ret 56 | 57 | end 58 | -------------------------------------------------------------------------------- /src/heap/base/stack.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_HEAP_BASE_STACK_H_ 6 | #define V8_HEAP_BASE_STACK_H_ 7 | 8 | #include "src/base/macros.h" 9 | 10 | namespace heap::base { 11 | 12 | class StackVisitor { 13 | public: 14 | virtual ~StackVisitor() = default; 15 | virtual void VisitPointer(const void* address) = 0; 16 | }; 17 | 18 | // Abstraction over the stack. Supports handling of: 19 | // - native stack; 20 | // - ASAN/MSAN; 21 | // - SafeStack: https://releases.llvm.org/10.0.0/tools/clang/docs/SafeStack.html 22 | class V8_EXPORT_PRIVATE Stack final { 23 | public: 24 | explicit Stack(const void* stack_start = nullptr); 25 | 26 | // Sets the start of the stack. 27 | void SetStackStart(const void* stack_start); 28 | 29 | // Returns true if |slot| is part of the stack and false otherwise. 30 | bool IsOnStack(void* slot) const; 31 | 32 | // Word-aligned iteration of the stack. Callee-saved registers are pushed to 33 | // the stack before iterating pointers. Slot values are passed on to 34 | // `visitor`. 35 | void IteratePointers(StackVisitor* visitor) const; 36 | 37 | // Word-aligned iteration of the stack, starting at `stack_end`. Slot values 38 | // are passed on to `visitor`. This is intended to be used with verifiers that 39 | // only visit a subset of the stack of IteratePointers(). 40 | // 41 | // **Ignores:** 42 | // - Callee-saved registers. 43 | // - SafeStack. 44 | void IteratePointersUnsafe(StackVisitor* visitor, uintptr_t stack_end) const; 45 | 46 | // Returns the start of the stack. 47 | const void* stack_start() const { return stack_start_; } 48 | 49 | // Sets, clears and gets the stack marker. 50 | void set_marker(const void* stack_marker); 51 | void clear_marker(); 52 | const void* get_marker() const; 53 | 54 | private: 55 | const void* stack_start_; 56 | const void* stack_marker_ = nullptr; 57 | }; 58 | 59 | } // namespace heap::base 60 | 61 | #endif // V8_HEAP_BASE_STACK_H_ 62 | -------------------------------------------------------------------------------- /src/heap/base/worklist.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/base/worklist.h" 6 | 7 | namespace heap::base::internal { 8 | 9 | // static 10 | SegmentBase* SegmentBase::GetSentinelSegmentAddress() { 11 | static SegmentBase sentinel_segment(0); 12 | return &sentinel_segment; 13 | } 14 | 15 | } // namespace heap::base::internal 16 | -------------------------------------------------------------------------------- /src/heap/cppgc/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | "+include/cppgc", 3 | ] 4 | -------------------------------------------------------------------------------- /src/heap/cppgc/caged-heap-local-data.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/internal/caged-heap-local-data.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "include/cppgc/platform.h" 11 | #include "src/base/macros.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | #if defined(CPPGC_YOUNG_GENERATION) 17 | 18 | static_assert( 19 | std::is_trivially_default_constructible::value, 20 | "To support lazy committing, AgeTable must be trivially constructible"); 21 | 22 | void AgeTable::SetAgeForRange(uintptr_t offset_begin, uintptr_t offset_end, 23 | Age age, 24 | AdjacentCardsPolicy adjacent_cards_policy) { 25 | // First, mark inner cards. 26 | const uintptr_t inner_card_offset_begin = 27 | RoundUp(offset_begin, kCardSizeInBytes); 28 | const uintptr_t outer_card_offset_end = 29 | RoundDown(offset_end, kCardSizeInBytes); 30 | 31 | for (auto inner_offset = inner_card_offset_begin; 32 | inner_offset < outer_card_offset_end; inner_offset += kCardSizeInBytes) 33 | SetAge(inner_offset, age); 34 | 35 | // If outer cards are not card-aligned and are not of the same age, mark them 36 | // as mixed. 37 | const auto set_age_for_outer_card = 38 | [this, age, adjacent_cards_policy](uintptr_t offset) { 39 | if (IsAligned(offset, kCardSizeInBytes)) return; 40 | if (adjacent_cards_policy == AdjacentCardsPolicy::kIgnore) 41 | SetAge(offset, age); 42 | else if (GetAge(offset) != age) 43 | SetAge(offset, AgeTable::Age::kMixed); 44 | }; 45 | 46 | set_age_for_outer_card(offset_begin); 47 | set_age_for_outer_card(offset_end); 48 | } 49 | 50 | AgeTable::Age AgeTable::GetAgeForRange(uintptr_t offset_begin, 51 | uintptr_t offset_end) const { 52 | Age result = GetAge(offset_begin); 53 | for (auto offset = offset_begin + kCardSizeInBytes; offset < offset_end; 54 | offset += kCardSizeInBytes) { 55 | if (result != GetAge(offset)) result = Age::kMixed; 56 | } 57 | return result; 58 | } 59 | 60 | void AgeTable::ResetForTesting() { 61 | std::fill(table_.begin(), table_.end(), Age::kOld); 62 | } 63 | 64 | #endif // defined(CPPGC_YOUNG_GENERATION) 65 | 66 | } // namespace internal 67 | } // namespace cppgc 68 | -------------------------------------------------------------------------------- /src/heap/cppgc/compaction-worklists.cc: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2020 the V8 project authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style license that can be 4 | // found in the LICENSE file. 5 | 6 | #include "src/heap/cppgc/compaction-worklists.h" 7 | 8 | namespace cppgc { 9 | namespace internal { 10 | 11 | void CompactionWorklists::ClearForTesting() { movable_slots_worklist_.Clear(); } 12 | 13 | } // namespace internal 14 | } // namespace cppgc 15 | -------------------------------------------------------------------------------- /src/heap/cppgc/compaction-worklists.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_HEAP_CPPGC_COMPACTION_WORKLISTS_H_ 6 | #define V8_HEAP_CPPGC_COMPACTION_WORKLISTS_H_ 7 | 8 | #include 9 | 10 | #include "src/heap/base/worklist.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | class CompactionWorklists final { 16 | public: 17 | CompactionWorklists() = default; 18 | 19 | CompactionWorklists(const CompactionWorklists&) = delete; 20 | CompactionWorklists& operator=(const CompactionWorklists&) = delete; 21 | 22 | using MovableReference = const void*; 23 | 24 | using MovableReferencesWorklist = 25 | heap::base::Worklist; 26 | 27 | MovableReferencesWorklist* movable_slots_worklist() { 28 | return &movable_slots_worklist_; 29 | } 30 | 31 | void ClearForTesting(); 32 | 33 | private: 34 | MovableReferencesWorklist movable_slots_worklist_; 35 | }; 36 | 37 | } // namespace internal 38 | } // namespace cppgc 39 | 40 | #endif // V8_HEAP_CPPGC_COMPACTION_WORKLISTS_H_ 41 | -------------------------------------------------------------------------------- /src/heap/cppgc/compactor.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_HEAP_CPPGC_COMPACTOR_H_ 6 | #define V8_HEAP_CPPGC_COMPACTOR_H_ 7 | 8 | #include "src/heap/cppgc/compaction-worklists.h" 9 | #include "src/heap/cppgc/garbage-collector.h" 10 | #include "src/heap/cppgc/raw-heap.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | class NormalPageSpace; 16 | 17 | class V8_EXPORT_PRIVATE Compactor final { 18 | using CompactableSpaceHandling = SweepingConfig::CompactableSpaceHandling; 19 | 20 | public: 21 | explicit Compactor(RawHeap&); 22 | ~Compactor() { DCHECK(!is_enabled_); } 23 | 24 | Compactor(const Compactor&) = delete; 25 | Compactor& operator=(const Compactor&) = delete; 26 | 27 | void InitializeIfShouldCompact(GCConfig::MarkingType, StackState); 28 | void CancelIfShouldNotCompact(GCConfig::MarkingType, StackState); 29 | // Returns whether spaces need to be processed by the Sweeper after 30 | // compaction. 31 | CompactableSpaceHandling CompactSpacesIfEnabled(); 32 | 33 | CompactionWorklists* compaction_worklists() { 34 | return compaction_worklists_.get(); 35 | } 36 | 37 | void EnableForNextGCForTesting(); 38 | bool IsEnabledForTesting() const { return is_enabled_; } 39 | 40 | private: 41 | bool ShouldCompact(GCConfig::MarkingType, StackState) const; 42 | 43 | RawHeap& heap_; 44 | // Compactor does not own the compactable spaces. The heap owns all spaces. 45 | std::vector compactable_spaces_; 46 | 47 | std::unique_ptr compaction_worklists_; 48 | 49 | bool is_enabled_ = false; 50 | bool is_cancelled_ = false; 51 | bool enable_for_next_gc_for_testing_ = false; 52 | }; 53 | 54 | } // namespace internal 55 | } // namespace cppgc 56 | 57 | #endif // V8_HEAP_CPPGC_COMPACTOR_H_ 58 | -------------------------------------------------------------------------------- /src/heap/cppgc/garbage-collector.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_HEAP_CPPGC_GARBAGE_COLLECTOR_H_ 6 | #define V8_HEAP_CPPGC_GARBAGE_COLLECTOR_H_ 7 | 8 | #include "include/cppgc/common.h" 9 | #include "src/heap/cppgc/heap-config.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | // GC interface that allows abstraction over the actual GC invocation. This is 15 | // needed to mock/fake GC for testing. 16 | class GarbageCollector { 17 | public: 18 | // Executes a garbage collection specified in config. 19 | virtual void CollectGarbage(GCConfig) = 0; 20 | virtual void StartIncrementalGarbageCollection(GCConfig) = 0; 21 | 22 | // The current epoch that the GC maintains. The epoch is increased on every 23 | // GC invocation. 24 | virtual size_t epoch() const = 0; 25 | 26 | // Returns a non-null state if the stack state if overriden. 27 | virtual const EmbedderStackState* override_stack_state() const = 0; 28 | }; 29 | 30 | } // namespace internal 31 | } // namespace cppgc 32 | 33 | #endif // V8_HEAP_CPPGC_GARBAGE_COLLECTOR_H_ 34 | -------------------------------------------------------------------------------- /src/heap/cppgc/gc-invoker.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_HEAP_CPPGC_GC_INVOKER_H_ 6 | #define V8_HEAP_CPPGC_GC_INVOKER_H_ 7 | 8 | #include "include/cppgc/common.h" 9 | #include "include/cppgc/heap.h" 10 | #include "src/base/macros.h" 11 | #include "src/heap/cppgc/garbage-collector.h" 12 | 13 | namespace cppgc { 14 | 15 | class Platform; 16 | 17 | namespace internal { 18 | 19 | // GC invoker that dispatches GC depending on StackSupport and StackState: 20 | // 1. If StackState specifies no stack scan needed the GC is invoked 21 | // synchronously. 22 | // 2. If StackState specifies conservative GC and StackSupport prohibits stack 23 | // scanning: Delay GC until it can be invoked without accessing the stack. 24 | // To do so, a precise GC without stack scan is scheduled using the platform 25 | // if non-nestable tasks are supported, and otherwise no operation is carried 26 | // out. This means that the heuristics allows to arbitrary go over the limit 27 | // in case non-nestable tasks are not supported and only conservative GCs are 28 | // requested. 29 | class V8_EXPORT_PRIVATE GCInvoker final : public GarbageCollector { 30 | public: 31 | GCInvoker(GarbageCollector*, cppgc::Platform*, cppgc::Heap::StackSupport); 32 | ~GCInvoker(); 33 | 34 | GCInvoker(const GCInvoker&) = delete; 35 | GCInvoker& operator=(const GCInvoker&) = delete; 36 | 37 | void CollectGarbage(GCConfig) final; 38 | void StartIncrementalGarbageCollection(GCConfig) final; 39 | size_t epoch() const final; 40 | const EmbedderStackState* override_stack_state() const final; 41 | 42 | private: 43 | class GCInvokerImpl; 44 | std::unique_ptr impl_; 45 | }; 46 | 47 | } // namespace internal 48 | } // namespace cppgc 49 | 50 | #endif // V8_HEAP_CPPGC_GC_INVOKER_H_ 51 | -------------------------------------------------------------------------------- /src/heap/cppgc/heap-consistency.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/heap-consistency.h" 6 | 7 | #include "include/cppgc/heap.h" 8 | #include "src/base/logging.h" 9 | #include "src/heap/cppgc/heap-base.h" 10 | 11 | namespace cppgc { 12 | namespace subtle { 13 | 14 | // static 15 | bool DisallowGarbageCollectionScope::IsGarbageCollectionAllowed( 16 | cppgc::HeapHandle& heap_handle) { 17 | auto& heap_base = internal::HeapBase::From(heap_handle); 18 | return !heap_base.in_disallow_gc_scope(); 19 | } 20 | 21 | // static 22 | void DisallowGarbageCollectionScope::Enter(cppgc::HeapHandle& heap_handle) { 23 | auto& heap_base = internal::HeapBase::From(heap_handle); 24 | heap_base.disallow_gc_scope_++; 25 | } 26 | 27 | // static 28 | void DisallowGarbageCollectionScope::Leave(cppgc::HeapHandle& heap_handle) { 29 | auto& heap_base = internal::HeapBase::From(heap_handle); 30 | DCHECK_GT(heap_base.disallow_gc_scope_, 0); 31 | heap_base.disallow_gc_scope_--; 32 | } 33 | 34 | DisallowGarbageCollectionScope::DisallowGarbageCollectionScope( 35 | cppgc::HeapHandle& heap_handle) 36 | : heap_handle_(heap_handle) { 37 | Enter(heap_handle); 38 | } 39 | 40 | DisallowGarbageCollectionScope::~DisallowGarbageCollectionScope() { 41 | Leave(heap_handle_); 42 | } 43 | 44 | // static 45 | void NoGarbageCollectionScope::Enter(cppgc::HeapHandle& heap_handle) { 46 | auto& heap_base = internal::HeapBase::From(heap_handle); 47 | heap_base.no_gc_scope_++; 48 | } 49 | 50 | // static 51 | void NoGarbageCollectionScope::Leave(cppgc::HeapHandle& heap_handle) { 52 | auto& heap_base = internal::HeapBase::From(heap_handle); 53 | DCHECK_GT(heap_base.no_gc_scope_, 0); 54 | heap_base.no_gc_scope_--; 55 | } 56 | 57 | NoGarbageCollectionScope::NoGarbageCollectionScope( 58 | cppgc::HeapHandle& heap_handle) 59 | : heap_handle_(heap_handle) { 60 | Enter(heap_handle); 61 | } 62 | 63 | NoGarbageCollectionScope::~NoGarbageCollectionScope() { Leave(heap_handle_); } 64 | 65 | } // namespace subtle 66 | } // namespace cppgc 67 | -------------------------------------------------------------------------------- /src/heap/cppgc/heap-growing.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_HEAP_CPPGC_HEAP_GROWING_H_ 6 | #define V8_HEAP_CPPGC_HEAP_GROWING_H_ 7 | 8 | #include "include/cppgc/heap.h" 9 | #include "src/base/macros.h" 10 | #include "src/heap/cppgc/globals.h" 11 | #include "src/heap/cppgc/raw-heap.h" 12 | 13 | namespace cppgc { 14 | 15 | class Platform; 16 | 17 | namespace internal { 18 | 19 | class GarbageCollector; 20 | class StatsCollector; 21 | 22 | // Growing strategy that invokes garbage collection using GarbageCollector based 23 | // on allocation statistics provided by StatsCollector and ResourceConstraints. 24 | // 25 | // Implements a fixed-ratio growing strategy with an initial heap size that the 26 | // GC can ignore to avoid excessive GCs for smaller heaps. 27 | class V8_EXPORT_PRIVATE HeapGrowing final { 28 | public: 29 | // Constant growing factor for growing the heap limit. 30 | static constexpr double kGrowingFactor = 1.5; 31 | // For smaller heaps, allow allocating at least LAB in each regular space 32 | // before triggering GC again. 33 | static constexpr size_t kMinLimitIncrease = 34 | kPageSize * RawHeap::kNumberOfRegularSpaces; 35 | 36 | HeapGrowing(GarbageCollector*, StatsCollector*, 37 | cppgc::Heap::ResourceConstraints, cppgc::Heap::MarkingType, 38 | cppgc::Heap::SweepingType); 39 | ~HeapGrowing(); 40 | 41 | HeapGrowing(const HeapGrowing&) = delete; 42 | HeapGrowing& operator=(const HeapGrowing&) = delete; 43 | 44 | size_t limit_for_atomic_gc() const; 45 | size_t limit_for_incremental_gc() const; 46 | 47 | void DisableForTesting(); 48 | 49 | private: 50 | class HeapGrowingImpl; 51 | std::unique_ptr impl_; 52 | }; 53 | 54 | } // namespace internal 55 | } // namespace cppgc 56 | 57 | #endif // V8_HEAP_CPPGC_HEAP_GROWING_H_ 58 | -------------------------------------------------------------------------------- /src/heap/cppgc/heap-object-header.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/heap-object-header.h" 6 | 7 | #include "include/cppgc/internal/api-constants.h" 8 | #include "src/base/macros.h" 9 | #include "src/base/sanitizer/asan.h" 10 | #include "src/heap/cppgc/gc-info-table.h" 11 | #include "src/heap/cppgc/heap-base.h" 12 | #include "src/heap/cppgc/heap-page.h" 13 | 14 | namespace cppgc { 15 | namespace internal { 16 | 17 | static_assert((kAllocationGranularity % sizeof(HeapObjectHeader)) == 0); 18 | 19 | void HeapObjectHeader::CheckApiConstants() { 20 | static_assert(api_constants::kFullyConstructedBitMask == 21 | FullyConstructedField::kMask); 22 | static_assert(api_constants::kFullyConstructedBitFieldOffsetFromPayload == 23 | (sizeof(encoded_high_) + sizeof(encoded_low_))); 24 | } 25 | 26 | void HeapObjectHeader::Finalize() { 27 | #ifdef V8_USE_ADDRESS_SANITIZER 28 | const size_t size = 29 | IsLargeObject() 30 | ? LargePage::From(BasePage::FromPayload(this))->ObjectSize() 31 | : ObjectSize(); 32 | ASAN_UNPOISON_MEMORY_REGION(ObjectStart(), size); 33 | #endif // V8_USE_ADDRESS_SANITIZER 34 | const GCInfo& gc_info = GlobalGCInfoTable::GCInfoFromIndex(GetGCInfoIndex()); 35 | if (gc_info.finalize) { 36 | gc_info.finalize(ObjectStart()); 37 | } 38 | } 39 | 40 | HeapObjectName HeapObjectHeader::GetName() const { 41 | const GCInfo& gc_info = GlobalGCInfoTable::GCInfoFromIndex(GetGCInfoIndex()); 42 | return gc_info.name( 43 | ObjectStart(), 44 | BasePage::FromPayload(this)->heap().name_of_unnamed_object()); 45 | } 46 | 47 | } // namespace internal 48 | } // namespace cppgc 49 | -------------------------------------------------------------------------------- /src/heap/cppgc/heap-space.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/heap-space.h" 6 | 7 | #include 8 | 9 | #include "src/base/logging.h" 10 | #include "src/base/platform/mutex.h" 11 | #include "src/heap/cppgc/heap-page.h" 12 | #include "src/heap/cppgc/object-start-bitmap.h" 13 | 14 | namespace cppgc { 15 | namespace internal { 16 | 17 | BaseSpace::BaseSpace(RawHeap* heap, size_t index, PageType type, 18 | bool is_compactable) 19 | : heap_(heap), index_(index), type_(type), is_compactable_(is_compactable) { 20 | USE(is_compactable_); 21 | } 22 | 23 | BaseSpace::~BaseSpace() = default; 24 | 25 | void BaseSpace::AddPage(BasePage* page) { 26 | v8::base::LockGuard lock(&pages_mutex_); 27 | DCHECK_EQ(pages_.cend(), std::find(pages_.cbegin(), pages_.cend(), page)); 28 | pages_.push_back(page); 29 | } 30 | 31 | void BaseSpace::RemovePage(BasePage* page) { 32 | v8::base::LockGuard lock(&pages_mutex_); 33 | auto it = std::find(pages_.cbegin(), pages_.cend(), page); 34 | DCHECK_NE(pages_.cend(), it); 35 | pages_.erase(it); 36 | } 37 | 38 | BaseSpace::Pages BaseSpace::RemoveAllPages() { 39 | Pages pages = std::move(pages_); 40 | pages_.clear(); 41 | return pages; 42 | } 43 | 44 | NormalPageSpace::NormalPageSpace(RawHeap* heap, size_t index, 45 | bool is_compactable) 46 | : BaseSpace(heap, index, PageType::kNormal, is_compactable) {} 47 | 48 | LargePageSpace::LargePageSpace(RawHeap* heap, size_t index) 49 | : BaseSpace(heap, index, PageType::kLarge, false /* is_compactable */) {} 50 | 51 | } // namespace internal 52 | } // namespace cppgc 53 | -------------------------------------------------------------------------------- /src/heap/cppgc/heap-state.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/heap-state.h" 6 | 7 | #include "src/heap/cppgc/heap-base.h" 8 | 9 | namespace cppgc { 10 | namespace subtle { 11 | 12 | // static 13 | bool HeapState::IsMarking(const HeapHandle& heap_handle) { 14 | const internal::MarkerBase* marker = 15 | internal::HeapBase::From(heap_handle).marker(); 16 | return marker && marker->IsMarking(); 17 | } 18 | 19 | // static 20 | bool HeapState::IsSweeping(const HeapHandle& heap_handle) { 21 | return internal::HeapBase::From(heap_handle).sweeper().IsSweepingInProgress(); 22 | } 23 | 24 | // static 25 | bool HeapState::IsSweepingOnOwningThread(const HeapHandle& heap_handle) { 26 | return internal::HeapBase::From(heap_handle) 27 | .sweeper() 28 | .IsSweepingOnMutatorThread(); 29 | } 30 | 31 | // static 32 | bool HeapState::IsInAtomicPause(const HeapHandle& heap_handle) { 33 | return internal::HeapBase::From(heap_handle).in_atomic_pause(); 34 | } 35 | 36 | // static 37 | bool HeapState::PreviousGCWasConservative(const HeapHandle& heap_handle) { 38 | return internal::HeapBase::From(heap_handle).stack_state_of_prev_gc() == 39 | EmbedderStackState::kMayContainHeapPointers; 40 | } 41 | 42 | } // namespace subtle 43 | } // namespace cppgc 44 | -------------------------------------------------------------------------------- /src/heap/cppgc/heap-statistics-collector.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 V8_HEAP_CPPGC_HEAP_STATISTICS_COLLECTOR_H_ 6 | #define V8_HEAP_CPPGC_HEAP_STATISTICS_COLLECTOR_H_ 7 | 8 | #include 9 | 10 | #include "include/cppgc/heap-statistics.h" 11 | #include "src/heap/cppgc/heap-visitor.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | class HeapStatisticsCollector : private HeapVisitor { 17 | friend class HeapVisitor; 18 | 19 | public: 20 | HeapStatistics CollectDetailedStatistics(HeapBase*); 21 | 22 | private: 23 | bool VisitNormalPageSpace(NormalPageSpace&); 24 | bool VisitLargePageSpace(LargePageSpace&); 25 | bool VisitNormalPage(NormalPage&); 26 | bool VisitLargePage(LargePage&); 27 | bool VisitHeapObjectHeader(HeapObjectHeader&); 28 | 29 | HeapStatistics* current_stats_; 30 | HeapStatistics::SpaceStatistics* current_space_stats_ = nullptr; 31 | HeapStatistics::PageStatistics* current_page_stats_ = nullptr; 32 | // Index from type name to final index in `HeapStats::type_names`. 33 | // Canonicalizing based on `const void*` assuming stable addresses. If the 34 | // implementation of `NameProvider` decides to return different type name 35 | // c-strings, the final outcome is less compact. 36 | std::unordered_map type_name_to_index_map_; 37 | }; 38 | 39 | } // namespace internal 40 | } // namespace cppgc 41 | 42 | #endif // V8_HEAP_CPPGC_HEAP_STATISTICS_COLLECTOR_H_ 43 | -------------------------------------------------------------------------------- /src/heap/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 V8_HEAP_CPPGC_HEAP_H_ 6 | #define V8_HEAP_CPPGC_HEAP_H_ 7 | 8 | #include "include/cppgc/heap.h" 9 | #include "include/cppgc/liveness-broker.h" 10 | #include "include/cppgc/macros.h" 11 | #include "src/heap/cppgc/garbage-collector.h" 12 | #include "src/heap/cppgc/gc-invoker.h" 13 | #include "src/heap/cppgc/heap-base.h" 14 | #include "src/heap/cppgc/heap-growing.h" 15 | 16 | namespace cppgc { 17 | namespace internal { 18 | 19 | class V8_EXPORT_PRIVATE Heap final : public HeapBase, 20 | public cppgc::Heap, 21 | public GarbageCollector { 22 | public: 23 | static Heap* From(cppgc::Heap* heap) { return static_cast(heap); } 24 | static const Heap* From(const cppgc::Heap* heap) { 25 | return static_cast(heap); 26 | } 27 | 28 | Heap(std::shared_ptr platform, 29 | cppgc::Heap::HeapOptions options); 30 | ~Heap() final; 31 | 32 | HeapBase& AsBase() { return *this; } 33 | const HeapBase& AsBase() const { return *this; } 34 | 35 | void CollectGarbage(GCConfig) final; 36 | void StartIncrementalGarbageCollection(GCConfig) final; 37 | void FinalizeIncrementalGarbageCollectionIfRunning(GCConfig); 38 | 39 | size_t epoch() const final { return epoch_; } 40 | const EmbedderStackState* override_stack_state() const final { 41 | return HeapBase::override_stack_state(); 42 | } 43 | 44 | void EnableGenerationalGC(); 45 | 46 | void DisableHeapGrowingForTesting(); 47 | 48 | private: 49 | void StartGarbageCollection(GCConfig); 50 | void FinalizeGarbageCollection(StackState); 51 | 52 | void FinalizeIncrementalGarbageCollectionIfNeeded(StackState) final; 53 | 54 | void StartIncrementalGarbageCollectionForTesting() final; 55 | void FinalizeIncrementalGarbageCollectionForTesting(EmbedderStackState) final; 56 | 57 | GCConfig config_; 58 | GCInvoker gc_invoker_; 59 | HeapGrowing growing_; 60 | bool generational_gc_enabled_ = false; 61 | 62 | size_t epoch_ = 0; 63 | }; 64 | 65 | } // namespace internal 66 | } // namespace cppgc 67 | 68 | #endif // V8_HEAP_CPPGC_HEAP_H_ 69 | -------------------------------------------------------------------------------- /src/heap/cppgc/incremental-marking-schedule.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_HEAP_CPPGC_INCREMENTAL_MARKING_SCHEDULE_H_ 6 | #define V8_HEAP_CPPGC_INCREMENTAL_MARKING_SCHEDULE_H_ 7 | 8 | #include 9 | 10 | #include "src/base/platform/time.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | class V8_EXPORT_PRIVATE IncrementalMarkingSchedule { 16 | public: 17 | // Estimated duration of GC cycle in milliseconds. 18 | static const double kEstimatedMarkingTimeMs; 19 | 20 | // Minimum number of bytes that should be marked during an incremental 21 | // marking step. 22 | static const size_t kMinimumMarkedBytesPerIncrementalStep; 23 | 24 | void NotifyIncrementalMarkingStart(); 25 | 26 | void UpdateMutatorThreadMarkedBytes(size_t); 27 | void AddConcurrentlyMarkedBytes(size_t); 28 | 29 | size_t GetOverallMarkedBytes() const; 30 | size_t GetConcurrentlyMarkedBytes() const; 31 | 32 | size_t GetNextIncrementalStepDuration(size_t); 33 | 34 | void SetElapsedTimeForTesting(double elapsed_time) { 35 | elapsed_time_for_testing_ = elapsed_time; 36 | } 37 | 38 | bool ShouldFlushEphemeronPairs(); 39 | 40 | private: 41 | double GetElapsedTimeInMs(v8::base::TimeTicks); 42 | 43 | v8::base::TimeTicks incremental_marking_start_time_; 44 | 45 | size_t mutator_thread_marked_bytes_ = 0; 46 | std::atomic_size_t concurrently_marked_bytes_{0}; 47 | 48 | // Using -1 as sentinel to denote 49 | static constexpr double kNoSetElapsedTimeForTesting = -1; 50 | double elapsed_time_for_testing_ = kNoSetElapsedTimeForTesting; 51 | 52 | static constexpr size_t kInvalidLastEstimatedLiveBytes = -1; 53 | size_t last_estimated_live_bytes_ = kInvalidLastEstimatedLiveBytes; 54 | double ephemeron_pairs_flushing_ratio_target = 0.25; 55 | static constexpr double kEphemeronPairsFlushingRatioIncrements = 0.25; 56 | }; 57 | 58 | } // namespace internal 59 | } // namespace cppgc 60 | 61 | #endif // V8_HEAP_CPPGC_INCREMENTAL_MARKING_SCHEDULE_H_ 62 | -------------------------------------------------------------------------------- /src/heap/cppgc/liveness-broker.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/liveness-broker.h" 6 | 7 | #include "src/heap/cppgc/heap-object-header.h" 8 | 9 | namespace cppgc { 10 | 11 | bool LivenessBroker::IsHeapObjectAliveImpl(const void* payload) const { 12 | return internal::HeapObjectHeader::FromObject(payload).IsMarked(); 13 | } 14 | 15 | namespace internal { 16 | 17 | // static 18 | cppgc::LivenessBroker LivenessBrokerFactory::Create() { 19 | return cppgc::LivenessBroker(); 20 | } 21 | 22 | } // namespace internal 23 | 24 | } // namespace cppgc 25 | -------------------------------------------------------------------------------- /src/heap/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 V8_HEAP_CPPGC_LIVENESS_BROKER_H_ 6 | #define V8_HEAP_CPPGC_LIVENESS_BROKER_H_ 7 | 8 | #include "include/cppgc/liveness-broker.h" 9 | #include "src/base/macros.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | class V8_EXPORT_PRIVATE LivenessBrokerFactory { 15 | public: 16 | static LivenessBroker Create(); 17 | }; 18 | 19 | } // namespace internal 20 | } // namespace cppgc 21 | 22 | #endif // V8_HEAP_CPPGC_LIVENESS_BROKER_H_ 23 | -------------------------------------------------------------------------------- /src/heap/cppgc/logging.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/internal/logging.h" 6 | #include "include/cppgc/source-location.h" 7 | 8 | #include "src/base/logging.h" 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | void DCheckImpl(const char* message, const SourceLocation& loc) { 14 | V8_Dcheck(loc.FileName(), static_cast(loc.Line()), message); 15 | } 16 | 17 | void FatalImpl(const char* message, const SourceLocation& loc) { 18 | #if DEBUG 19 | V8_Fatal(loc.FileName(), static_cast(loc.Line()), "Check failed: %s.", 20 | message); 21 | #elif !defined(OFFICIAL_BUILD) 22 | V8_Fatal("Check failed: %s.", message); 23 | #else 24 | V8_Fatal("ignored"); 25 | #endif 26 | } 27 | 28 | } // namespace internal 29 | } // namespace cppgc 30 | -------------------------------------------------------------------------------- /src/heap/cppgc/marking-state.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/marking-state.h" 6 | 7 | #include 8 | 9 | #include "src/heap/cppgc/heap-base.h" 10 | #include "src/heap/cppgc/stats-collector.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | void MutatorMarkingState::FlushNotFullyConstructedObjects() { 16 | std::unordered_set objects = 17 | not_fully_constructed_worklist_.Extract(); 18 | for (HeapObjectHeader* object : objects) { 19 | if (MarkNoPush(*object)) 20 | previously_not_fully_constructed_worklist_.Push(object); 21 | } 22 | } 23 | 24 | void MutatorMarkingState::FlushDiscoveredEphemeronPairs() { 25 | StatsCollector::EnabledScope stats_scope( 26 | heap_.stats_collector(), StatsCollector::kMarkFlushEphemerons); 27 | discovered_ephemeron_pairs_worklist_.Publish(); 28 | if (!discovered_ephemeron_pairs_worklist_.IsGlobalEmpty()) { 29 | ephemeron_pairs_for_processing_worklist_.Merge( 30 | discovered_ephemeron_pairs_worklist_); 31 | } 32 | } 33 | 34 | } // namespace internal 35 | } // namespace cppgc 36 | -------------------------------------------------------------------------------- /src/heap/cppgc/marking-worklists.cc: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2020 the V8 project authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style license that can be 4 | // found in the LICENSE file. 5 | 6 | #include "src/heap/cppgc/marking-worklists.h" 7 | 8 | namespace cppgc { 9 | namespace internal { 10 | 11 | constexpr int MarkingWorklists::kMutatorThreadId; 12 | 13 | void MarkingWorklists::ClearForTesting() { 14 | marking_worklist_.Clear(); 15 | not_fully_constructed_worklist_.Clear(); 16 | previously_not_fully_constructed_worklist_.Clear(); 17 | write_barrier_worklist_.Clear(); 18 | weak_callback_worklist_.Clear(); 19 | parallel_weak_callback_worklist_.Clear(); 20 | concurrent_marking_bailout_worklist_.Clear(); 21 | discovered_ephemeron_pairs_worklist_.Clear(); 22 | ephemeron_pairs_for_processing_worklist_.Clear(); 23 | retrace_marked_objects_worklist_.Clear(); 24 | } 25 | 26 | MarkingWorklists::ExternalMarkingWorklist::~ExternalMarkingWorklist() { 27 | DCHECK(IsEmpty()); 28 | } 29 | 30 | } // namespace internal 31 | } // namespace cppgc 32 | -------------------------------------------------------------------------------- /src/heap/cppgc/member-storage.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | #include "include/cppgc/internal/member-storage.h" 6 | 7 | #include "include/cppgc/garbage-collected.h" 8 | #include "include/cppgc/member.h" 9 | #include "src/base/compiler-specific.h" 10 | #include "src/base/macros.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | #if defined(CPPGC_POINTER_COMPRESSION) 16 | uintptr_t CageBaseGlobal::g_base_ = CageBaseGlobal::kLowerHalfWordMask; 17 | #endif // defined(CPPGC_POINTER_COMPRESSION) 18 | 19 | // Debugging helpers. 20 | 21 | #if defined(CPPGC_POINTER_COMPRESSION) 22 | extern "C" V8_DONT_STRIP_SYMBOL V8_EXPORT_PRIVATE void* 23 | _cppgc_internal_Decompress_Compressed_Pointer(uint32_t cmprsd) { 24 | return MemberStorage::Decompress(cmprsd); 25 | } 26 | #endif // !defined(CPPGC_POINTER_COMPRESSION) 27 | 28 | class MemberDebugHelper final { 29 | public: 30 | static void* PrintUncompressed(MemberBase* m) { 31 | return const_cast(m->GetRaw()); 32 | } 33 | }; 34 | 35 | extern "C" V8_DONT_STRIP_SYMBOL V8_EXPORT_PRIVATE void* 36 | _cppgc_internal_Print_Member(MemberBase* m) { 37 | return MemberDebugHelper::PrintUncompressed(m); 38 | } 39 | 40 | } // namespace internal 41 | } // namespace cppgc 42 | -------------------------------------------------------------------------------- /src/heap/cppgc/member-storage.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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_HEAP_CPPGC_MEMBER_STORAGE_H_ 6 | #define V8_HEAP_CPPGC_MEMBER_STORAGE_H_ 7 | 8 | #include "include/cppgc/internal/member-storage.h" 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | #if defined(CPPGC_POINTER_COMPRESSION) 14 | class CageBaseGlobalUpdater final { 15 | public: 16 | CageBaseGlobalUpdater() = delete; 17 | static void UpdateCageBase(uintptr_t cage_base) { 18 | CPPGC_DCHECK(CageBaseGlobal::IsBaseConsistent()); 19 | CPPGC_DCHECK(0u == (cage_base & CageBaseGlobal::kLowerHalfWordMask)); 20 | CageBaseGlobal::g_base_ = cage_base | CageBaseGlobal::kLowerHalfWordMask; 21 | } 22 | 23 | static uintptr_t GetCageBase() { 24 | CPPGC_DCHECK(CageBaseGlobal::IsBaseConsistent()); 25 | return CageBaseGlobal::g_base_ & ~CageBaseGlobal::kLowerHalfWordMask; 26 | } 27 | }; 28 | #endif // defined(CPPGC_POINTER_COMPRESSION) 29 | 30 | } // namespace internal 31 | } // namespace cppgc 32 | 33 | #endif // V8_HEAP_CPPGC_MEMBER_STORAGE_H_ 34 | -------------------------------------------------------------------------------- /src/heap/cppgc/memory.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/memory.h" 6 | 7 | #include 8 | 9 | #include "src/heap/cppgc/globals.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | void NoSanitizeMemset(void* address, char c, size_t bytes) { 15 | volatile uint8_t* const base = static_cast(address); 16 | for (size_t i = 0; i < bytes; ++i) { 17 | base[i] = c; 18 | } 19 | } 20 | 21 | } // namespace internal 22 | } // namespace cppgc 23 | -------------------------------------------------------------------------------- /src/heap/cppgc/metric-recorder.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 V8_HEAP_CPPGC_METRIC_RECORDER_H_ 6 | #define V8_HEAP_CPPGC_METRIC_RECORDER_H_ 7 | 8 | #include 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | class StatsCollector; 14 | 15 | /** 16 | * Base class used for reporting GC statistics histograms. Embedders interested 17 | * in collecting histograms should implement the virtual AddMainThreadEvent 18 | * methods below and pass an instance of the implementation during Heap 19 | * creation. 20 | */ 21 | class MetricRecorder { 22 | public: 23 | struct GCCycle { 24 | enum class Type { kMinor, kMajor }; 25 | struct IncrementalPhases { 26 | int64_t mark_duration_us = -1; 27 | int64_t sweep_duration_us = -1; 28 | }; 29 | struct Phases : public IncrementalPhases { 30 | int64_t weak_duration_us = -1; 31 | int64_t compact_duration_us = -1; 32 | }; 33 | struct Sizes { 34 | int64_t before_bytes = -1; 35 | int64_t after_bytes = -1; 36 | int64_t freed_bytes = -1; 37 | }; 38 | 39 | Type type = Type::kMajor; 40 | Phases total; 41 | Phases main_thread; 42 | Phases main_thread_atomic; 43 | IncrementalPhases main_thread_incremental; 44 | Sizes objects; 45 | Sizes memory; 46 | double collection_rate_in_percent; 47 | double efficiency_in_bytes_per_us; 48 | double main_thread_efficiency_in_bytes_per_us; 49 | }; 50 | 51 | struct MainThreadIncrementalMark { 52 | int64_t duration_us = -1; 53 | }; 54 | 55 | struct MainThreadIncrementalSweep { 56 | int64_t duration_us = -1; 57 | }; 58 | 59 | virtual ~MetricRecorder() = default; 60 | 61 | virtual void AddMainThreadEvent(const GCCycle& event) {} 62 | virtual void AddMainThreadEvent(const MainThreadIncrementalMark& event) {} 63 | virtual void AddMainThreadEvent(const MainThreadIncrementalSweep& event) {} 64 | }; 65 | 66 | } // namespace internal 67 | } // namespace cppgc 68 | 69 | #endif // V8_HEAP_CPPGC_METRIC_RECORDER_H_ 70 | -------------------------------------------------------------------------------- /src/heap/cppgc/name-trait.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/internal/name-trait.h" 6 | 7 | #include 8 | 9 | #include "src/base/logging.h" 10 | #include "src/base/macros.h" 11 | 12 | namespace cppgc { 13 | 14 | // static 15 | constexpr const char NameProvider::kHiddenName[]; 16 | 17 | // static 18 | constexpr const char NameProvider::kNoNameDeducible[]; 19 | 20 | namespace internal { 21 | 22 | // static 23 | HeapObjectName NameTraitBase::GetNameFromTypeSignature(const char* signature) { 24 | // Parsing string of structure: 25 | // static HeapObjectName NameTrait::GetNameFor(...) [T = int] 26 | if (!signature) return {NameProvider::kNoNameDeducible, true}; 27 | 28 | const std::string raw(signature); 29 | const auto start_pos = raw.rfind("T = ") + 4; 30 | DCHECK_NE(std::string::npos, start_pos); 31 | const auto len = raw.length() - start_pos - 1; 32 | const std::string name = raw.substr(start_pos, len).c_str(); 33 | char* name_buffer = new char[name.length() + 1]; 34 | int written = snprintf(name_buffer, name.length() + 1, "%s", name.c_str()); 35 | DCHECK_EQ(static_cast(written), name.length()); 36 | USE(written); 37 | return {name_buffer, false}; 38 | } 39 | 40 | } // namespace internal 41 | } // namespace cppgc 42 | -------------------------------------------------------------------------------- /src/heap/cppgc/object-poisoner.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 V8_HEAP_CPPGC_OBJECT_POISONER_H_ 6 | #define V8_HEAP_CPPGC_OBJECT_POISONER_H_ 7 | 8 | #include "src/base/sanitizer/asan.h" 9 | #include "src/heap/cppgc/heap-object-header.h" 10 | #include "src/heap/cppgc/heap-page.h" 11 | #include "src/heap/cppgc/heap-visitor.h" 12 | #include "src/heap/cppgc/object-view.h" 13 | 14 | namespace cppgc { 15 | namespace internal { 16 | 17 | #ifdef V8_USE_ADDRESS_SANITIZER 18 | 19 | // Poisons the payload of unmarked objects. 20 | class UnmarkedObjectsPoisoner : public HeapVisitor { 21 | friend class HeapVisitor; 22 | 23 | private: 24 | bool VisitHeapObjectHeader(HeapObjectHeader& header) { 25 | if (header.IsFree() || header.IsMarked()) return true; 26 | 27 | ASAN_POISON_MEMORY_REGION(header.ObjectStart(), 28 | ObjectView<>(header).Size()); 29 | return true; 30 | } 31 | }; 32 | 33 | #endif // V8_USE_ADDRESS_SANITIZER 34 | 35 | } // namespace internal 36 | } // namespace cppgc 37 | 38 | #endif // V8_HEAP_CPPGC_OBJECT_POISONER_H_ 39 | -------------------------------------------------------------------------------- /src/heap/cppgc/object-size-trait.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/object-size-trait.h" 6 | 7 | #include "src/heap/cppgc/heap-object-header.h" 8 | #include "src/heap/cppgc/heap-page.h" 9 | #include "src/heap/cppgc/object-view.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | // static 15 | size_t BaseObjectSizeTrait::GetObjectSizeForGarbageCollected( 16 | const void* object) { 17 | return ObjectView(HeapObjectHeader::FromObject(object)) 18 | .Size(); 19 | } 20 | 21 | // static 22 | size_t BaseObjectSizeTrait::GetObjectSizeForGarbageCollectedMixin( 23 | const void* address) { 24 | // `address` is guaranteed to be on a normal page because large object mixins 25 | // are not supported. 26 | const auto& header = 27 | BasePage::FromPayload(address) 28 | ->ObjectHeaderFromInnerAddress(address); 29 | DCHECK(!header.IsLargeObject()); 30 | return header.ObjectSize(); 31 | } 32 | 33 | } // namespace internal 34 | } // namespace cppgc 35 | -------------------------------------------------------------------------------- /src/heap/cppgc/object-view.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 V8_HEAP_CPPGC_OBJECT_VIEW_H_ 6 | #define V8_HEAP_CPPGC_OBJECT_VIEW_H_ 7 | 8 | #include "include/v8config.h" 9 | #include "src/heap/cppgc/globals.h" 10 | #include "src/heap/cppgc/heap-object-header.h" 11 | #include "src/heap/cppgc/heap-page.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | // ObjectView allows accessing a header within the bounds of the actual object. 17 | // It is not exposed externally and does not keep the underlying object alive. 18 | template 19 | class ObjectView final { 20 | public: 21 | V8_INLINE explicit ObjectView(const HeapObjectHeader& header); 22 | 23 | V8_INLINE Address Start() const; 24 | V8_INLINE ConstAddress End() const; 25 | V8_INLINE size_t Size() const; 26 | 27 | private: 28 | const HeapObjectHeader& header_; 29 | const BasePage* base_page_; 30 | const bool is_large_object_; 31 | }; 32 | 33 | template 34 | ObjectView::ObjectView(const HeapObjectHeader& header) 35 | : header_(header), 36 | base_page_( 37 | BasePage::FromPayload(const_cast(&header_))), 38 | is_large_object_(header_.IsLargeObject()) { 39 | DCHECK_EQ(Start() + Size(), End()); 40 | } 41 | 42 | template 43 | Address ObjectView::Start() const { 44 | return header_.ObjectStart(); 45 | } 46 | 47 | template 48 | ConstAddress ObjectView::End() const { 49 | return is_large_object_ ? LargePage::From(base_page_)->PayloadEnd() 50 | : header_.ObjectEnd(); 51 | } 52 | 53 | template 54 | size_t ObjectView::Size() const { 55 | return is_large_object_ ? LargePage::From(base_page_)->ObjectSize() 56 | : header_.ObjectSize(); 57 | } 58 | 59 | } // namespace internal 60 | } // namespace cppgc 61 | 62 | #endif // V8_HEAP_CPPGC_OBJECT_VIEW_H_ 63 | -------------------------------------------------------------------------------- /src/heap/cppgc/platform.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 V8_HEAP_CPPGC_PLATFORM_H_ 6 | #define V8_HEAP_CPPGC_PLATFORM_H_ 7 | 8 | #include 9 | 10 | #include "include/cppgc/source-location.h" 11 | #include "src/base/macros.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | class HeapBase; 17 | 18 | class V8_EXPORT_PRIVATE FatalOutOfMemoryHandler final { 19 | public: 20 | using Callback = void(const std::string&, const SourceLocation&, HeapBase*); 21 | 22 | FatalOutOfMemoryHandler() = default; 23 | explicit FatalOutOfMemoryHandler(HeapBase* heap) : heap_(heap) {} 24 | 25 | [[noreturn]] void operator()( 26 | const std::string& reason = std::string(), 27 | const SourceLocation& = SourceLocation::Current()) const; 28 | 29 | void SetCustomHandler(Callback*); 30 | 31 | // Disallow copy/move. 32 | FatalOutOfMemoryHandler(const FatalOutOfMemoryHandler&) = delete; 33 | FatalOutOfMemoryHandler& operator=(const FatalOutOfMemoryHandler&) = delete; 34 | 35 | private: 36 | HeapBase* heap_ = nullptr; 37 | Callback* custom_handler_ = nullptr; 38 | }; 39 | 40 | // Gets the global OOM handler that is not bound to any specific Heap instance. 41 | FatalOutOfMemoryHandler& GetGlobalOOMHandler(); 42 | 43 | } // namespace internal 44 | } // namespace cppgc 45 | 46 | #endif // V8_HEAP_CPPGC_PLATFORM_H_ 47 | -------------------------------------------------------------------------------- /src/heap/cppgc/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 V8_HEAP_CPPGC_PREFINALIZER_HANDLER_H_ 6 | #define V8_HEAP_CPPGC_PREFINALIZER_HANDLER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "include/cppgc/prefinalizer.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | class HeapBase; 17 | 18 | struct PreFinalizer final { 19 | using Callback = PrefinalizerRegistration::Callback; 20 | 21 | void* object; 22 | Callback callback; 23 | 24 | bool operator==(const PreFinalizer& other) const; 25 | }; 26 | 27 | class PreFinalizerHandler final { 28 | public: 29 | explicit PreFinalizerHandler(HeapBase& heap); 30 | 31 | void RegisterPrefinalizer(PreFinalizer pre_finalizer); 32 | 33 | void InvokePreFinalizers(); 34 | 35 | bool IsInvokingPreFinalizers() const { return is_invoking_; } 36 | 37 | void NotifyAllocationInPrefinalizer(size_t); 38 | size_t ExtractBytesAllocatedInPrefinalizers() { 39 | return std::exchange(bytes_allocated_in_prefinalizers, 0); 40 | } 41 | 42 | private: 43 | // Checks that the current thread is the thread that created the heap. 44 | bool CurrentThreadIsCreationThread(); 45 | 46 | // Pre-finalizers are called in the reverse order in which they are 47 | // registered by the constructors (including constructors of Mixin 48 | // objects) for an object, by processing the ordered_pre_finalizers_ 49 | // back-to-front. 50 | std::vector ordered_pre_finalizers_; 51 | std::vector* current_ordered_pre_finalizers_; 52 | 53 | HeapBase& heap_; 54 | bool is_invoking_ = false; 55 | #ifdef DEBUG 56 | int creation_thread_id_; 57 | #endif 58 | 59 | // Counter of bytes allocated during prefinalizers. 60 | size_t bytes_allocated_in_prefinalizers = 0u; 61 | }; 62 | 63 | } // namespace internal 64 | } // namespace cppgc 65 | 66 | #endif // V8_HEAP_CPPGC_PREFINALIZER_HANDLER_H_ 67 | -------------------------------------------------------------------------------- /src/heap/cppgc/process-heap-statistics.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/process-heap-statistics.h" 6 | 7 | namespace cppgc { 8 | 9 | std::atomic_size_t ProcessHeapStatistics::total_allocated_space_{0}; 10 | std::atomic_size_t ProcessHeapStatistics::total_allocated_object_size_{0}; 11 | 12 | } // namespace cppgc 13 | -------------------------------------------------------------------------------- /src/heap/cppgc/process-heap.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/process-heap.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "src/base/lazy-instance.h" 11 | #include "src/base/logging.h" 12 | #include "src/base/platform/mutex.h" 13 | #include "src/heap/cppgc/heap-base.h" 14 | #include "src/heap/cppgc/page-memory.h" 15 | 16 | namespace cppgc { 17 | namespace internal { 18 | 19 | v8::base::LazyMutex g_process_mutex = LAZY_MUTEX_INITIALIZER; 20 | 21 | namespace { 22 | 23 | v8::base::LazyMutex g_heap_registry_mutex = LAZY_MUTEX_INITIALIZER; 24 | 25 | HeapRegistry::Storage& GetHeapRegistryStorage() { 26 | static v8::base::LazyInstance::type heap_registry = 27 | LAZY_INSTANCE_INITIALIZER; 28 | return *heap_registry.Pointer(); 29 | } 30 | 31 | } // namespace 32 | 33 | // static 34 | void HeapRegistry::RegisterHeap(HeapBase& heap) { 35 | v8::base::MutexGuard guard(g_heap_registry_mutex.Pointer()); 36 | 37 | auto& storage = GetHeapRegistryStorage(); 38 | DCHECK_EQ(storage.end(), std::find(storage.begin(), storage.end(), &heap)); 39 | storage.push_back(&heap); 40 | } 41 | 42 | // static 43 | void HeapRegistry::UnregisterHeap(HeapBase& heap) { 44 | v8::base::MutexGuard guard(g_heap_registry_mutex.Pointer()); 45 | 46 | // HeapRegistry requires access to PageBackend which means it must still 47 | // be present by the time a heap is removed from the registry. 48 | DCHECK_NOT_NULL(heap.page_backend()); 49 | 50 | auto& storage = GetHeapRegistryStorage(); 51 | const auto pos = std::find(storage.begin(), storage.end(), &heap); 52 | DCHECK_NE(storage.end(), pos); 53 | storage.erase(pos); 54 | } 55 | 56 | // static 57 | HeapBase* HeapRegistry::TryFromManagedPointer(const void* needle) { 58 | v8::base::MutexGuard guard(g_heap_registry_mutex.Pointer()); 59 | 60 | for (auto* heap : GetHeapRegistryStorage()) { 61 | const auto address = 62 | heap->page_backend()->Lookup(reinterpret_cast(needle)); 63 | if (address) return heap; 64 | } 65 | return nullptr; 66 | } 67 | 68 | // static 69 | const HeapRegistry::Storage& HeapRegistry::GetRegisteredHeapsForTesting() { 70 | return GetHeapRegistryStorage(); 71 | } 72 | 73 | } // namespace internal 74 | } // namespace cppgc 75 | -------------------------------------------------------------------------------- /src/heap/cppgc/process-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 V8_HEAP_CPPGC_PROCESS_HEAP_H_ 6 | #define V8_HEAP_CPPGC_PROCESS_HEAP_H_ 7 | 8 | #include 9 | 10 | #include "src/base/macros.h" 11 | #include "src/base/platform/mutex.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | class HeapBase; 17 | 18 | extern v8::base::LazyMutex g_process_mutex; 19 | 20 | class V8_EXPORT_PRIVATE HeapRegistry final { 21 | public: 22 | using Storage = std::vector; 23 | 24 | class Subscription final { 25 | public: 26 | inline explicit Subscription(HeapBase&); 27 | inline ~Subscription(); 28 | 29 | private: 30 | HeapBase& heap_; 31 | }; 32 | 33 | static HeapBase* TryFromManagedPointer(const void* needle); 34 | 35 | // Does not take the registry mutex and is thus only useful for testing. 36 | static const Storage& GetRegisteredHeapsForTesting(); 37 | 38 | private: 39 | static void RegisterHeap(HeapBase&); 40 | static void UnregisterHeap(HeapBase&); 41 | }; 42 | 43 | HeapRegistry::Subscription::Subscription(HeapBase& heap) : heap_(heap) { 44 | HeapRegistry::RegisterHeap(heap_); 45 | } 46 | 47 | HeapRegistry::Subscription::~Subscription() { 48 | HeapRegistry::UnregisterHeap(heap_); 49 | } 50 | 51 | } // namespace internal 52 | } // namespace cppgc 53 | 54 | #endif // V8_HEAP_CPPGC_PROCESS_HEAP_H_ 55 | -------------------------------------------------------------------------------- /src/heap/cppgc/raw-heap.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/raw-heap.h" 6 | 7 | #include "src/heap/cppgc/heap-space.h" 8 | 9 | namespace cppgc { 10 | namespace internal { 11 | 12 | // static 13 | constexpr size_t RawHeap::kNumberOfRegularSpaces; 14 | 15 | RawHeap::RawHeap( 16 | HeapBase* heap, 17 | const std::vector>& custom_spaces) 18 | : main_heap_(heap) { 19 | size_t i = 0; 20 | for (; i < static_cast(RegularSpaceType::kLarge); ++i) { 21 | spaces_.push_back(std::make_unique(this, i, false)); 22 | } 23 | spaces_.push_back(std::make_unique( 24 | this, static_cast(RegularSpaceType::kLarge))); 25 | DCHECK_EQ(kNumberOfRegularSpaces, spaces_.size()); 26 | for (size_t j = 0; j < custom_spaces.size(); j++) { 27 | spaces_.push_back(std::make_unique( 28 | this, kNumberOfRegularSpaces + j, custom_spaces[j]->IsCompactable())); 29 | } 30 | } 31 | 32 | RawHeap::~RawHeap() = default; 33 | 34 | } // namespace internal 35 | } // namespace cppgc 36 | -------------------------------------------------------------------------------- /src/heap/cppgc/source-location.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/source-location.h" 6 | 7 | namespace cppgc { 8 | 9 | std::string SourceLocation::ToString() const { 10 | if (!file_) { 11 | return {}; 12 | } 13 | return std::string(function_) + "@" + file_ + ":" + std::to_string(line_); 14 | } 15 | 16 | } // namespace cppgc 17 | -------------------------------------------------------------------------------- /src/heap/cppgc/task-handle.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_HEAP_CPPGC_TASK_HANDLE_H_ 6 | #define V8_HEAP_CPPGC_TASK_HANDLE_H_ 7 | 8 | #include 9 | 10 | #include "src/base/logging.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | // A handle that is used for cancelling individual tasks. 16 | struct SingleThreadedHandle { 17 | struct NonEmptyTag {}; 18 | 19 | // Default construction results in empty handle. 20 | SingleThreadedHandle() = default; 21 | 22 | explicit SingleThreadedHandle(NonEmptyTag) 23 | : is_cancelled_(std::make_shared(false)) {} 24 | 25 | void Cancel() { 26 | DCHECK(is_cancelled_); 27 | *is_cancelled_ = true; 28 | } 29 | 30 | bool IsCanceled() const { 31 | DCHECK(is_cancelled_); 32 | return *is_cancelled_; 33 | } 34 | 35 | // A handle is active if it is non-empty and not cancelled. 36 | explicit operator bool() const { 37 | return is_cancelled_.get() && !*is_cancelled_.get(); 38 | } 39 | 40 | private: 41 | std::shared_ptr is_cancelled_; 42 | }; 43 | 44 | } // namespace internal 45 | } // namespace cppgc 46 | 47 | #endif // V8_HEAP_CPPGC_TASK_HANDLE_H_ 48 | -------------------------------------------------------------------------------- /src/heap/cppgc/testing.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/testing.h" 6 | 7 | #include "src/base/logging.h" 8 | #include "src/heap/cppgc/heap-base.h" 9 | 10 | namespace cppgc { 11 | namespace testing { 12 | 13 | OverrideEmbedderStackStateScope::OverrideEmbedderStackStateScope( 14 | HeapHandle& heap_handle, EmbedderStackState state) 15 | : heap_handle_(heap_handle) { 16 | auto& heap = internal::HeapBase::From(heap_handle_); 17 | CHECK_NULL(heap.override_stack_state_.get()); 18 | heap.override_stack_state_ = std::make_unique(state); 19 | } 20 | 21 | OverrideEmbedderStackStateScope::~OverrideEmbedderStackStateScope() { 22 | internal::HeapBase::From(heap_handle_).override_stack_state_.reset(); 23 | } 24 | 25 | StandaloneTestingHeap::StandaloneTestingHeap(HeapHandle& heap_handle) 26 | : heap_handle_(heap_handle) {} 27 | 28 | void StandaloneTestingHeap::StartGarbageCollection() { 29 | internal::HeapBase::From(heap_handle_) 30 | .StartIncrementalGarbageCollectionForTesting(); 31 | } 32 | 33 | bool StandaloneTestingHeap::PerformMarkingStep(EmbedderStackState stack_state) { 34 | return internal::HeapBase::From(heap_handle_) 35 | .marker() 36 | ->IncrementalMarkingStepForTesting(stack_state); 37 | } 38 | 39 | void StandaloneTestingHeap::FinalizeGarbageCollection( 40 | EmbedderStackState stack_state) { 41 | internal::HeapBase::From(heap_handle_) 42 | .FinalizeIncrementalGarbageCollectionForTesting(stack_state); 43 | } 44 | 45 | void StandaloneTestingHeap::ToggleMainThreadMarking(bool should_mark) { 46 | internal::HeapBase::From(heap_handle_) 47 | .marker() 48 | ->SetMainThreadMarkingDisabledForTesting(!should_mark); 49 | } 50 | 51 | void StandaloneTestingHeap::ForceCompactionForNextGarbageCollection() { 52 | internal::HeapBase::From(heap_handle_) 53 | .compactor() 54 | .EnableForNextGCForTesting(); 55 | } 56 | 57 | bool IsHeapObjectOld(void* object) { 58 | #if defined(CPPGC_YOUNG_GENERATION) 59 | return internal::HeapObjectHeader::FromObject(object).IsMarked(); 60 | #else 61 | return true; 62 | #endif 63 | } 64 | 65 | } // namespace testing 66 | } // namespace cppgc 67 | -------------------------------------------------------------------------------- /src/heap/cppgc/trace-trait.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/trace-trait.h" 6 | 7 | #include "src/heap/cppgc/gc-info-table.h" 8 | #include "src/heap/cppgc/heap-page.h" 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | TraceDescriptor TraceTraitFromInnerAddressImpl::GetTraceDescriptor( 14 | const void* address) { 15 | // address is guaranteed to be on a normal page because this is used only for 16 | // mixins. 17 | const BasePage* page = BasePage::FromPayload(address); 18 | page->SynchronizedLoad(); 19 | const HeapObjectHeader& header = 20 | page->ObjectHeaderFromInnerAddress(address); 21 | return {header.ObjectStart(), 22 | GlobalGCInfoTable::GCInfoFromIndex( 23 | header.GetGCInfoIndex()) 24 | .trace}; 25 | } 26 | 27 | } // namespace internal 28 | } // namespace cppgc 29 | -------------------------------------------------------------------------------- /src/heap/cppgc/unmarker.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 V8_HEAP_CPPGC_UNMARKER_H_ 6 | #define V8_HEAP_CPPGC_UNMARKER_H_ 7 | 8 | #include "src/heap/cppgc/heap-object-header.h" 9 | #include "src/heap/cppgc/heap-visitor.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | class SequentialUnmarker final : private HeapVisitor { 15 | friend class HeapVisitor; 16 | 17 | public: 18 | explicit SequentialUnmarker(RawHeap& heap) { Traverse(heap); } 19 | 20 | private: 21 | bool VisitHeapObjectHeader(HeapObjectHeader& header) { 22 | if (header.IsMarked()) header.Unmark(); 23 | return true; 24 | } 25 | }; 26 | 27 | } // namespace internal 28 | } // namespace cppgc 29 | 30 | #endif // V8_HEAP_CPPGC_UNMARKER_H_ 31 | -------------------------------------------------------------------------------- /src/heap/cppgc/virtual-memory.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/virtual-memory.h" 6 | 7 | #include "include/cppgc/platform.h" 8 | #include "src/base/macros.h" 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | VirtualMemory::VirtualMemory(PageAllocator* page_allocator, size_t size, 14 | size_t alignment, void* hint) 15 | : page_allocator_(page_allocator) { 16 | DCHECK_NOT_NULL(page_allocator); 17 | DCHECK(IsAligned(size, page_allocator->CommitPageSize())); 18 | 19 | const size_t page_size = page_allocator_->AllocatePageSize(); 20 | start_ = page_allocator->AllocatePages(hint, RoundUp(size, page_size), 21 | RoundUp(alignment, page_size), 22 | PageAllocator::kNoAccess); 23 | if (start_) { 24 | size_ = RoundUp(size, page_size); 25 | } 26 | } 27 | 28 | VirtualMemory::~VirtualMemory() V8_NOEXCEPT { 29 | if (IsReserved()) { 30 | page_allocator_->FreePages(start_, size_); 31 | } 32 | } 33 | 34 | VirtualMemory::VirtualMemory(VirtualMemory&& other) V8_NOEXCEPT 35 | : page_allocator_(std::move(other.page_allocator_)), 36 | start_(std::move(other.start_)), 37 | size_(std::move(other.size_)) { 38 | other.Reset(); 39 | } 40 | 41 | VirtualMemory& VirtualMemory::operator=(VirtualMemory&& other) V8_NOEXCEPT { 42 | DCHECK(!IsReserved()); 43 | page_allocator_ = std::move(other.page_allocator_); 44 | start_ = std::move(other.start_); 45 | size_ = std::move(other.size_); 46 | other.Reset(); 47 | return *this; 48 | } 49 | 50 | void VirtualMemory::Reset() { 51 | start_ = nullptr; 52 | size_ = 0; 53 | } 54 | 55 | } // namespace internal 56 | } // namespace cppgc 57 | -------------------------------------------------------------------------------- /src/heap/cppgc/virtual-memory.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_HEAP_CPPGC_VIRTUAL_MEMORY_H_ 6 | #define V8_HEAP_CPPGC_VIRTUAL_MEMORY_H_ 7 | 8 | #include 9 | 10 | #include "include/cppgc/platform.h" 11 | #include "src/base/macros.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | // Represents and controls an area of reserved memory. 17 | class V8_EXPORT_PRIVATE VirtualMemory { 18 | public: 19 | // Empty VirtualMemory object, controlling no reserved memory. 20 | VirtualMemory() = default; 21 | 22 | // Reserves virtual memory containing an area of the given size that is 23 | // aligned per |alignment| rounded up to the |page_allocator|'s allocate page 24 | // size. The |size| is aligned with |page_allocator|'s commit page size. 25 | VirtualMemory(PageAllocator*, size_t size, size_t alignment, 26 | void* hint = nullptr); 27 | 28 | // Releases the reserved memory, if any, controlled by this VirtualMemory 29 | // object. 30 | ~VirtualMemory() V8_NOEXCEPT; 31 | 32 | VirtualMemory(VirtualMemory&&) V8_NOEXCEPT; 33 | VirtualMemory& operator=(VirtualMemory&&) V8_NOEXCEPT; 34 | 35 | // Returns whether the memory has been reserved. 36 | bool IsReserved() const { return start_ != nullptr; } 37 | 38 | void* address() const { 39 | DCHECK(IsReserved()); 40 | return start_; 41 | } 42 | 43 | size_t size() const { 44 | DCHECK(IsReserved()); 45 | return size_; 46 | } 47 | 48 | private: 49 | // Resets to the default state. 50 | void Reset(); 51 | 52 | PageAllocator* page_allocator_ = nullptr; 53 | void* start_ = nullptr; 54 | size_t size_ = 0; 55 | }; 56 | 57 | } // namespace internal 58 | } // namespace cppgc 59 | 60 | #endif // V8_HEAP_CPPGC_VIRTUAL_MEMORY_H_ 61 | -------------------------------------------------------------------------------- /src/heap/cppgc/write-barrier.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 V8_HEAP_CPPGC_WRITE_BARRIER_H_ 6 | #define V8_HEAP_CPPGC_WRITE_BARRIER_H_ 7 | 8 | #include "include/cppgc/internal/write-barrier.h" 9 | #include "src/base/lazy-instance.h" 10 | #include "src/base/platform/mutex.h" 11 | 12 | namespace cppgc { 13 | namespace internal { 14 | 15 | class WriteBarrier::FlagUpdater final { 16 | public: 17 | static void Enter() { write_barrier_enabled_.Enter(); } 18 | static void Exit() { write_barrier_enabled_.Exit(); } 19 | 20 | private: 21 | FlagUpdater() = delete; 22 | }; 23 | 24 | #if defined(CPPGC_YOUNG_GENERATION) 25 | class V8_EXPORT_PRIVATE YoungGenerationEnabler final { 26 | public: 27 | static void Enable(); 28 | static void Disable(); 29 | 30 | static bool IsEnabled(); 31 | 32 | private: 33 | template 34 | friend class v8::base::LeakyObject; 35 | 36 | static YoungGenerationEnabler& Instance(); 37 | 38 | YoungGenerationEnabler() = default; 39 | 40 | size_t is_enabled_; 41 | v8::base::Mutex mutex_; 42 | }; 43 | #endif // defined(CPPGC_YOUNG_GENERATION) 44 | 45 | } // namespace internal 46 | } // namespace cppgc 47 | 48 | #endif // V8_HEAP_CPPGC_WRITE_BARRIER_H_ 49 | -------------------------------------------------------------------------------- /src/libplatform/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | "-include", 3 | "+include/libplatform", 4 | "+include/v8-platform.h", 5 | "-src", 6 | "+src/base", 7 | "+src/libplatform", 8 | ] 9 | -------------------------------------------------------------------------------- /src/libplatform/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 | } -------------------------------------------------------------------------------- /src/libplatform/OWNERS: -------------------------------------------------------------------------------- 1 | mlippautz@chromium.org 2 | -------------------------------------------------------------------------------- /src/libplatform/default-worker-threads-task-runner.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_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_ 6 | #define V8_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "include/libplatform/libplatform-export.h" 12 | #include "include/v8-platform.h" 13 | #include "src/base/platform/mutex.h" 14 | #include "src/base/platform/platform.h" 15 | #include "src/libplatform/delayed-task-queue.h" 16 | 17 | namespace v8 { 18 | namespace platform { 19 | 20 | class V8_PLATFORM_EXPORT DefaultWorkerThreadsTaskRunner 21 | : public NON_EXPORTED_BASE(TaskRunner) { 22 | public: 23 | using TimeFunction = double (*)(); 24 | 25 | DefaultWorkerThreadsTaskRunner(uint32_t thread_pool_size, 26 | TimeFunction time_function); 27 | 28 | ~DefaultWorkerThreadsTaskRunner() override; 29 | 30 | void Terminate(); 31 | 32 | double MonotonicallyIncreasingTime(); 33 | 34 | // v8::TaskRunner implementation. 35 | void PostTask(std::unique_ptr task) override; 36 | 37 | void PostDelayedTask(std::unique_ptr task, 38 | double delay_in_seconds) override; 39 | 40 | void PostIdleTask(std::unique_ptr task) override; 41 | 42 | bool IdleTasksEnabled() override; 43 | 44 | private: 45 | class WorkerThread : public base::Thread { 46 | public: 47 | explicit WorkerThread(DefaultWorkerThreadsTaskRunner* runner); 48 | ~WorkerThread() override; 49 | 50 | WorkerThread(const WorkerThread&) = delete; 51 | WorkerThread& operator=(const WorkerThread&) = delete; 52 | 53 | // This thread attempts to get tasks in a loop from |runner_| and run them. 54 | void Run() override; 55 | 56 | private: 57 | DefaultWorkerThreadsTaskRunner* runner_; 58 | }; 59 | 60 | // Called by the WorkerThread. Gets the next take (delayed or immediate) to be 61 | // executed. Blocks if no task is available. 62 | std::unique_ptr GetNext(); 63 | 64 | bool terminated_ = false; 65 | base::Mutex lock_; 66 | std::vector> thread_pool_; 67 | // Worker threads access this queue, so we can only destroy it after all 68 | // workers stopped. 69 | DelayedTaskQueue queue_; 70 | TimeFunction time_function_; 71 | }; 72 | 73 | } // namespace platform 74 | } // namespace v8 75 | 76 | #endif // V8_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_ 77 | -------------------------------------------------------------------------------- /src/libplatform/etw/etw-provider-win.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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_ETW_ETW_PROVIDER_WIN_H_ 6 | #define V8_LIBPLATFORM_ETW_ETW_PROVIDER_WIN_H_ 7 | 8 | // This file defines all the ETW Provider functions. 9 | #include 10 | #ifndef VOID 11 | #define VOID void 12 | #endif 13 | #include 14 | #include 15 | #include // defines TRACE_LEVEL_* and EVENT_TRACE_TYPE_* 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #if defined(__clang__) 23 | #pragma clang diagnostic ignored "-Wc++98-compat-extra-semi" 24 | #endif 25 | 26 | #ifndef V8_ETW_GUID 27 | #define V8_ETW_GUID \ 28 | 0x57277741, 0x3638, 0x4A4B, 0xBD, 0xBA, 0x0A, 0xC6, 0xE4, 0x5D, 0xA5, 0x6C 29 | #endif // V8_ETW_GUID 30 | 31 | #define V8_DECLARE_TRACELOGGING_PROVIDER(v8Provider) \ 32 | TRACELOGGING_DECLARE_PROVIDER(v8Provider); 33 | 34 | #define V8_DEFINE_TRACELOGGING_PROVIDER(v8Provider) \ 35 | TRACELOGGING_DEFINE_PROVIDER(v8Provider, "V8.js", (V8_ETW_GUID)); 36 | 37 | #endif // V8_LIBPLATFORM_ETW_ETW_PROVIDER_WIN_H_ 38 | -------------------------------------------------------------------------------- /src/libplatform/task-queue.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "src/libplatform/task-queue.h" 6 | 7 | #include "include/v8-platform.h" 8 | #include "src/base/logging.h" 9 | #include "src/base/platform/platform.h" 10 | #include "src/base/platform/time.h" 11 | 12 | namespace v8 { 13 | namespace platform { 14 | 15 | TaskQueue::TaskQueue() : process_queue_semaphore_(0), terminated_(false) {} 16 | 17 | 18 | TaskQueue::~TaskQueue() { 19 | base::MutexGuard guard(&lock_); 20 | DCHECK(terminated_); 21 | DCHECK(task_queue_.empty()); 22 | } 23 | 24 | void TaskQueue::Append(std::unique_ptr task) { 25 | base::MutexGuard guard(&lock_); 26 | DCHECK(!terminated_); 27 | task_queue_.push(std::move(task)); 28 | process_queue_semaphore_.Signal(); 29 | } 30 | 31 | std::unique_ptr TaskQueue::GetNext() { 32 | for (;;) { 33 | { 34 | base::MutexGuard guard(&lock_); 35 | if (!task_queue_.empty()) { 36 | std::unique_ptr result = std::move(task_queue_.front()); 37 | task_queue_.pop(); 38 | return result; 39 | } 40 | if (terminated_) { 41 | process_queue_semaphore_.Signal(); 42 | return nullptr; 43 | } 44 | } 45 | process_queue_semaphore_.Wait(); 46 | } 47 | } 48 | 49 | 50 | void TaskQueue::Terminate() { 51 | base::MutexGuard guard(&lock_); 52 | DCHECK(!terminated_); 53 | terminated_ = true; 54 | process_queue_semaphore_.Signal(); 55 | } 56 | 57 | void TaskQueue::BlockUntilQueueEmptyForTesting() { 58 | for (;;) { 59 | { 60 | base::MutexGuard guard(&lock_); 61 | if (task_queue_.empty()) return; 62 | } 63 | base::OS::Sleep(base::TimeDelta::FromMilliseconds(5)); 64 | } 65 | } 66 | 67 | } // namespace platform 68 | } // namespace v8 69 | -------------------------------------------------------------------------------- /src/libplatform/task-queue.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_TASK_QUEUE_H_ 6 | #define V8_LIBPLATFORM_TASK_QUEUE_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "include/libplatform/libplatform-export.h" 12 | #include "src/base/platform/mutex.h" 13 | #include "src/base/platform/semaphore.h" 14 | #include 15 | 16 | namespace v8 { 17 | 18 | class Task; 19 | 20 | namespace platform { 21 | 22 | class V8_PLATFORM_EXPORT TaskQueue { 23 | public: 24 | TaskQueue(); 25 | ~TaskQueue(); 26 | 27 | TaskQueue(const TaskQueue&) = delete; 28 | TaskQueue& operator=(const TaskQueue&) = delete; 29 | 30 | // Appends a task to the queue. The queue takes ownership of |task|. 31 | void Append(std::unique_ptr task); 32 | 33 | // Returns the next task to process. Blocks if no task is available. Returns 34 | // nullptr if the queue is terminated. 35 | std::unique_ptr GetNext(); 36 | 37 | // Terminate the queue. 38 | void Terminate(); 39 | 40 | private: 41 | FRIEND_TEST(WorkerThreadTest, PostSingleTask); 42 | 43 | void BlockUntilQueueEmptyForTesting(); 44 | 45 | base::Semaphore process_queue_semaphore_; 46 | base::Mutex lock_; 47 | std::queue> task_queue_; 48 | bool terminated_; 49 | }; 50 | 51 | } // namespace platform 52 | } // namespace v8 53 | 54 | 55 | #endif // V8_LIBPLATFORM_TASK_QUEUE_H_ 56 | -------------------------------------------------------------------------------- /src/libplatform/tracing/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | "+libplatform", 3 | "+perfetto", 4 | "+protos/perfetto", 5 | ] 6 | -------------------------------------------------------------------------------- /src/libplatform/tracing/OWNERS: -------------------------------------------------------------------------------- 1 | cbruni@chromium.org 2 | -------------------------------------------------------------------------------- /src/libplatform/tracing/recorder-mac.cc: -------------------------------------------------------------------------------- 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 | #ifndef V8_LIBPLATFORM_TRACING_RECORDER_MAC_H_ 5 | #define V8_LIBPLATFORM_TRACING_RECORDER_MAC_H_ 6 | 7 | #include "src/libplatform/tracing/recorder.h" 8 | 9 | #pragma clang diagnostic push 10 | #pragma clang diagnostic ignored "-Wunguarded-availability" 11 | 12 | namespace v8 { 13 | namespace platform { 14 | namespace tracing { 15 | 16 | Recorder::Recorder() { v8Provider = os_log_create("v8", ""); } 17 | Recorder::~Recorder() {} 18 | 19 | bool Recorder::IsEnabled() { 20 | return os_log_type_enabled(v8Provider, OS_LOG_TYPE_DEFAULT); 21 | } 22 | bool Recorder::IsEnabled(const uint8_t level) { 23 | if (level == OS_LOG_TYPE_DEFAULT || level == OS_LOG_TYPE_INFO || 24 | level == OS_LOG_TYPE_DEBUG || level == OS_LOG_TYPE_ERROR || 25 | level == OS_LOG_TYPE_FAULT) { 26 | return os_log_type_enabled(v8Provider, static_cast(level)); 27 | } 28 | return false; 29 | } 30 | 31 | void Recorder::AddEvent(TraceObject* trace_event) { 32 | os_signpost_event_emit(v8Provider, OS_SIGNPOST_ID_EXCLUSIVE, "", 33 | "%s, cpu_duration: %d", trace_event->name(), 34 | static_cast(trace_event->cpu_duration())); 35 | } 36 | 37 | } // namespace tracing 38 | } // namespace platform 39 | } // namespace v8 40 | 41 | #pragma clang diagnostic pop 42 | 43 | #endif // V8_LIBPLATFORM_TRACING_RECORDER_MAC_H_ 44 | -------------------------------------------------------------------------------- /src/libplatform/tracing/recorder-win.cc: -------------------------------------------------------------------------------- 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 | #ifndef V8_LIBPLATFORM_TRACING_RECORDER_WIN_H_ 5 | #define V8_LIBPLATFORM_TRACING_RECORDER_WIN_H_ 6 | 7 | #include "src/libplatform/etw/etw-provider-win.h" 8 | #include "src/libplatform/tracing/recorder.h" 9 | 10 | namespace v8 { 11 | namespace platform { 12 | namespace tracing { 13 | 14 | V8_DECLARE_TRACELOGGING_PROVIDER(g_v8LibProvider); 15 | V8_DEFINE_TRACELOGGING_PROVIDER(g_v8LibProvider); 16 | 17 | Recorder::Recorder() { TraceLoggingRegister(g_v8LibProvider); } 18 | 19 | Recorder::~Recorder() { 20 | if (g_v8LibProvider) { 21 | TraceLoggingUnregister(g_v8LibProvider); 22 | } 23 | } 24 | 25 | bool Recorder::IsEnabled() { 26 | return TraceLoggingProviderEnabled(g_v8LibProvider, 0, 0); 27 | } 28 | 29 | bool Recorder::IsEnabled(const uint8_t level) { 30 | return TraceLoggingProviderEnabled(g_v8LibProvider, level, 0); 31 | } 32 | 33 | void Recorder::AddEvent(TraceObject* trace_event) { 34 | // TODO(sartang@microsoft.com): Figure out how to write the conditional 35 | // arguments 36 | wchar_t wName[4096]; 37 | MultiByteToWideChar(CP_ACP, 0, trace_event->name(), -1, wName, 4096); 38 | 39 | #if defined(V8_USE_PERFETTO) 40 | const wchar_t* wCategoryGroupName = L""; 41 | #else // defined(V8_USE_PERFETTO) 42 | wchar_t wCategoryGroupName[4096]; 43 | MultiByteToWideChar(CP_ACP, 0, 44 | TracingController::GetCategoryGroupName( 45 | trace_event->category_enabled_flag()), 46 | -1, wCategoryGroupName, 4096); 47 | #endif // !defined(V8_USE_PERFETTO) 48 | 49 | TraceLoggingWrite(g_v8LibProvider, "", TraceLoggingValue(wName, "Event Name"), 50 | TraceLoggingValue(trace_event->pid(), "pid"), 51 | TraceLoggingValue(trace_event->tid(), "tid"), 52 | TraceLoggingValue(trace_event->ts(), "ts"), 53 | TraceLoggingValue(trace_event->tts(), "tts"), 54 | TraceLoggingValue(trace_event->phase(), "phase"), 55 | TraceLoggingValue(wCategoryGroupName, "category"), 56 | TraceLoggingValue(trace_event->duration(), "dur"), 57 | TraceLoggingValue(trace_event->cpu_duration(), "tdur")); 58 | } 59 | 60 | } // namespace tracing 61 | } // namespace platform 62 | } // namespace v8 63 | 64 | #endif // V8_LIBPLATFORM_TRACING_RECORDER_WIN_H_ 65 | -------------------------------------------------------------------------------- /src/libplatform/tracing/recorder.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_LIBPLATFORM_TRACING_RECORDER_H_ 6 | #define V8_LIBPLATFORM_TRACING_RECORDER_H_ 7 | 8 | #include 9 | 10 | #include "include/libplatform/v8-tracing.h" 11 | 12 | #if V8_OS_DARWIN 13 | #include 14 | #pragma clang diagnostic push 15 | #pragma clang diagnostic ignored "-Wunguarded-availability" 16 | #endif 17 | 18 | #if !defined(V8_ENABLE_SYSTEM_INSTRUMENTATION) 19 | #error "only include this file if V8_ENABLE_SYSTEM_INSTRUMENTATION" 20 | #endif // V8_ENABLE_SYSTEM_INSTRUMENTATION 21 | 22 | namespace v8 { 23 | namespace platform { 24 | namespace tracing { 25 | 26 | // This class serves as a base class for emitting events to system event 27 | // controllers: ETW for Windows, Signposts on Mac (to be implemented). It is 28 | // enabled by turning on both the ENABLE_SYSTEM_INSTRUMENTATION build flag and 29 | // the --enable-system-instrumentation command line flag. When enabled, it is 30 | // called from within SystemInstrumentationTraceWriter and replaces the 31 | // JSONTraceWriter for event-tracing. 32 | class V8_PLATFORM_EXPORT Recorder { 33 | public: 34 | Recorder(); 35 | ~Recorder(); 36 | 37 | bool IsEnabled(); 38 | bool IsEnabled(const uint8_t level); 39 | 40 | void AddEvent(TraceObject* trace_event); 41 | 42 | private: 43 | #if V8_OS_DARWIN 44 | os_log_t v8Provider; 45 | #endif 46 | }; 47 | 48 | } // namespace tracing 49 | } // namespace platform 50 | } // namespace v8 51 | 52 | #if V8_OS_DARWIN 53 | #pragma clang diagnostic pop 54 | #endif 55 | 56 | #endif // V8_LIBPLATFORM_TRACING_RECORDER_H_ 57 | -------------------------------------------------------------------------------- /src/libplatform/tracing/trace-buffer.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_TRACING_TRACE_BUFFER_H_ 6 | #define V8_LIBPLATFORM_TRACING_TRACE_BUFFER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include "include/libplatform/v8-tracing.h" 12 | #include "src/base/platform/mutex.h" 13 | 14 | namespace v8 { 15 | namespace platform { 16 | namespace tracing { 17 | 18 | class TraceBufferRingBuffer : public TraceBuffer { 19 | public: 20 | // Takes ownership of |trace_writer|. 21 | TraceBufferRingBuffer(size_t max_chunks, TraceWriter* trace_writer); 22 | ~TraceBufferRingBuffer() override = default; 23 | 24 | TraceObject* AddTraceEvent(uint64_t* handle) override; 25 | TraceObject* GetEventByHandle(uint64_t handle) override; 26 | bool Flush() override; 27 | 28 | private: 29 | uint64_t MakeHandle(size_t chunk_index, uint32_t chunk_seq, 30 | size_t event_index) const; 31 | void ExtractHandle(uint64_t handle, size_t* chunk_index, uint32_t* chunk_seq, 32 | size_t* event_index) const; 33 | size_t Capacity() const { return max_chunks_ * TraceBufferChunk::kChunkSize; } 34 | size_t NextChunkIndex(size_t index) const; 35 | 36 | mutable base::Mutex mutex_; 37 | size_t max_chunks_; 38 | std::unique_ptr trace_writer_; 39 | std::vector> chunks_; 40 | size_t chunk_index_; 41 | bool is_empty_ = true; 42 | uint32_t current_chunk_seq_ = 1; 43 | }; 44 | 45 | } // namespace tracing 46 | } // namespace platform 47 | } // namespace v8 48 | 49 | #endif // V8_LIBPLATFORM_TRACING_TRACE_BUFFER_H_ 50 | -------------------------------------------------------------------------------- /src/libplatform/tracing/trace-config.cc: -------------------------------------------------------------------------------- 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 | #include 6 | 7 | #include "include/libplatform/v8-tracing.h" 8 | #include "src/base/logging.h" 9 | 10 | namespace v8 { 11 | 12 | class Isolate; 13 | 14 | namespace platform { 15 | namespace tracing { 16 | 17 | TraceConfig* TraceConfig::CreateDefaultTraceConfig() { 18 | TraceConfig* trace_config = new TraceConfig(); 19 | trace_config->included_categories_.push_back("v8"); 20 | return trace_config; 21 | } 22 | 23 | bool TraceConfig::IsCategoryGroupEnabled(const char* category_group) const { 24 | std::stringstream category_stream(category_group); 25 | while (category_stream.good()) { 26 | std::string category; 27 | getline(category_stream, category, ','); 28 | for (const auto& included_category : included_categories_) { 29 | if (category == included_category) return true; 30 | } 31 | } 32 | return false; 33 | } 34 | 35 | void TraceConfig::AddIncludedCategory(const char* included_category) { 36 | DCHECK(included_category != nullptr && strlen(included_category) > 0); 37 | included_categories_.push_back(included_category); 38 | } 39 | 40 | } // namespace tracing 41 | } // namespace platform 42 | } // namespace v8 43 | -------------------------------------------------------------------------------- /src/libplatform/tracing/trace-event-listener.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | #include "src/libplatform/tracing/trace-event-listener.h" 6 | 7 | #include "protos/perfetto/trace/trace.pb.h" 8 | #include "src/base/logging.h" 9 | 10 | namespace v8 { 11 | namespace platform { 12 | namespace tracing { 13 | 14 | void TraceEventListener::ParseFromArray(const std::vector& array) { 15 | perfetto::protos::Trace trace; 16 | CHECK(trace.ParseFromArray(array.data(), static_cast(array.size()))); 17 | 18 | for (int i = 0; i < trace.packet_size(); i++) { 19 | // TODO(petermarshall): ChromeTracePacket instead. 20 | const perfetto::protos::TracePacket& packet = trace.packet(i); 21 | ProcessPacket(packet); 22 | } 23 | } 24 | 25 | } // namespace tracing 26 | } // namespace platform 27 | } // namespace v8 28 | -------------------------------------------------------------------------------- /src/libplatform/tracing/trace-event-listener.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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_TRACING_TRACE_EVENT_LISTENER_H_ 6 | #define V8_LIBPLATFORM_TRACING_TRACE_EVENT_LISTENER_H_ 7 | 8 | #include 9 | 10 | #include "libplatform/libplatform-export.h" 11 | 12 | namespace perfetto { 13 | namespace protos { 14 | class TracePacket; 15 | } // namespace protos 16 | } // namespace perfetto 17 | 18 | namespace v8 { 19 | namespace platform { 20 | namespace tracing { 21 | 22 | // A TraceEventListener is a simple interface that allows subclasses to listen 23 | // to trace events. This interface is to hide the more complex interactions that 24 | // the PerfettoConsumer class has to perform. Clients override ProcessPacket() 25 | // to respond to trace events, e.g. to write them to a file as JSON or for 26 | // testing purposes. 27 | class V8_PLATFORM_EXPORT TraceEventListener { 28 | public: 29 | virtual ~TraceEventListener() = default; 30 | virtual void ProcessPacket(const ::perfetto::protos::TracePacket& packet) = 0; 31 | 32 | void ParseFromArray(const std::vector& array); 33 | }; 34 | 35 | } // namespace tracing 36 | } // namespace platform 37 | } // namespace v8 38 | 39 | #endif // V8_LIBPLATFORM_TRACING_TRACE_EVENT_LISTENER_H_ 40 | -------------------------------------------------------------------------------- /src/libplatform/tracing/trace-writer.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_TRACING_TRACE_WRITER_H_ 6 | #define V8_LIBPLATFORM_TRACING_TRACE_WRITER_H_ 7 | 8 | #include "include/libplatform/v8-tracing.h" 9 | 10 | namespace v8 { 11 | namespace platform { 12 | namespace tracing { 13 | 14 | class Recorder; 15 | 16 | class JSONTraceWriter : public TraceWriter { 17 | public: 18 | explicit JSONTraceWriter(std::ostream& stream); 19 | JSONTraceWriter(std::ostream& stream, const std::string& tag); 20 | ~JSONTraceWriter() override; 21 | void AppendTraceEvent(TraceObject* trace_event) override; 22 | void Flush() override; 23 | 24 | private: 25 | void AppendArgValue(uint8_t type, TraceObject::ArgValue value); 26 | void AppendArgValue(v8::ConvertableToTraceFormat*); 27 | 28 | std::ostream& stream_; 29 | bool append_comma_ = false; 30 | }; 31 | 32 | #if defined(V8_ENABLE_SYSTEM_INSTRUMENTATION) 33 | class SystemInstrumentationTraceWriter : public TraceWriter { 34 | public: 35 | SystemInstrumentationTraceWriter(); 36 | ~SystemInstrumentationTraceWriter() override; 37 | void AppendTraceEvent(TraceObject* trace_event) override; 38 | void Flush() override; 39 | 40 | private: 41 | std::unique_ptr recorder_; 42 | }; 43 | #endif 44 | 45 | } // namespace tracing 46 | } // namespace platform 47 | } // namespace v8 48 | 49 | #endif // V8_LIBPLATFORM_TRACING_TRACE_WRITER_H_ 50 | -------------------------------------------------------------------------------- /src/libplatform/worker-thread.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "src/libplatform/worker-thread.h" 6 | 7 | #include "include/v8-platform.h" 8 | #include "src/libplatform/task-queue.h" 9 | 10 | namespace v8 { 11 | namespace platform { 12 | 13 | WorkerThread::WorkerThread(TaskQueue* queue) 14 | : Thread(Options("V8 WorkerThread")), queue_(queue) { 15 | CHECK(Start()); 16 | } 17 | 18 | WorkerThread::~WorkerThread() { 19 | Join(); 20 | } 21 | 22 | void WorkerThread::Run() { 23 | while (std::unique_ptr task = queue_->GetNext()) { 24 | task->Run(); 25 | } 26 | } 27 | 28 | } // namespace platform 29 | } // namespace v8 30 | -------------------------------------------------------------------------------- /src/libplatform/worker-thread.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_WORKER_THREAD_H_ 6 | #define V8_LIBPLATFORM_WORKER_THREAD_H_ 7 | 8 | #include 9 | 10 | #include "include/libplatform/libplatform-export.h" 11 | #include "src/base/compiler-specific.h" 12 | #include "src/base/platform/platform.h" 13 | 14 | namespace v8 { 15 | 16 | namespace platform { 17 | 18 | class TaskQueue; 19 | 20 | class V8_PLATFORM_EXPORT WorkerThread : public NON_EXPORTED_BASE(base::Thread) { 21 | public: 22 | explicit WorkerThread(TaskQueue* queue); 23 | ~WorkerThread() override; 24 | 25 | WorkerThread(const WorkerThread&) = delete; 26 | WorkerThread& operator=(const WorkerThread&) = delete; 27 | 28 | // Thread implementation. 29 | void Run() override; 30 | 31 | private: 32 | TaskQueue* queue_; 33 | }; 34 | 35 | } // namespace platform 36 | } // namespace v8 37 | 38 | 39 | #endif // V8_LIBPLATFORM_WORKER_THREAD_H_ 40 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/liveness-broker-unittest.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/liveness-broker.h" 6 | 7 | #include "include/cppgc/allocation.h" 8 | #include "include/cppgc/garbage-collected.h" 9 | #include "src/heap/cppgc/heap-object-header.h" 10 | #include "src/heap/cppgc/liveness-broker.h" 11 | #include "test/unittests/heap/cppgc/tests.h" 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | namespace { 17 | 18 | using LivenessBrokerTest = testing::TestSupportingAllocationOnly; 19 | 20 | class GCed : public GarbageCollected { 21 | public: 22 | void Trace(cppgc::Visitor*) const {} 23 | }; 24 | 25 | } // namespace 26 | 27 | TEST_F(LivenessBrokerTest, IsHeapObjectAliveForConstPointer) { 28 | // Regression test: http://crbug.com/661363. 29 | GCed* object = MakeGarbageCollected(GetAllocationHandle()); 30 | HeapObjectHeader& header = HeapObjectHeader::FromObject(object); 31 | LivenessBroker broker = internal::LivenessBrokerFactory::Create(); 32 | EXPECT_TRUE(header.TryMarkAtomic()); 33 | EXPECT_TRUE(broker.IsHeapObjectAlive(object)); 34 | const GCed* const_object = const_cast(object); 35 | EXPECT_TRUE(broker.IsHeapObjectAlive(const_object)); 36 | } 37 | 38 | TEST_F(LivenessBrokerTest, IsHeapObjectAliveNullptr) { 39 | GCed* object = nullptr; 40 | LivenessBroker broker = internal::LivenessBrokerFactory::Create(); 41 | EXPECT_TRUE(broker.IsHeapObjectAlive(object)); 42 | } 43 | 44 | } // namespace internal 45 | } // namespace cppgc 46 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/logging-unittest.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/internal/logging.h" 6 | 7 | #include 8 | 9 | #include "include/cppgc/source-location.h" 10 | #include 11 | #include 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | namespace { 17 | // GCC < 9 has a bug due to which calling non-constexpr functions are not 18 | // allowed even on constexpr path: 19 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67026. 20 | #if !defined(__GNUC__) || defined(__clang__) 21 | constexpr int CheckInConstexpr(int a) { 22 | CPPGC_DCHECK(a > 0); 23 | CPPGC_CHECK(a > 0); 24 | return a; 25 | } 26 | #endif 27 | } // namespace 28 | 29 | TEST(LoggingTest, Pass) { 30 | CPPGC_DCHECK(true); 31 | CPPGC_CHECK(true); 32 | } 33 | 34 | TEST(LoggingTest, Fail) { 35 | #if DEBUG 36 | EXPECT_DEATH_IF_SUPPORTED(CPPGC_DCHECK(false), ""); 37 | #endif 38 | EXPECT_DEATH_IF_SUPPORTED(CPPGC_CHECK(false), ""); 39 | } 40 | 41 | TEST(LoggingTest, DontReportUnused) { 42 | int a = 1; 43 | CPPGC_DCHECK(a); 44 | } 45 | 46 | #if !defined(__GNUC__) || defined(__clang__) 47 | TEST(LoggingTest, ConstexprContext) { 48 | constexpr int a = CheckInConstexpr(1); 49 | CPPGC_DCHECK(a); 50 | } 51 | #endif 52 | 53 | #if DEBUG && !defined(OFFICIAL_BUILD) 54 | TEST(LoggingTest, Message) { 55 | using ::testing::ContainsRegex; 56 | EXPECT_DEATH_IF_SUPPORTED(CPPGC_DCHECK(5 == 7), 57 | ContainsRegex("failed.*5 == 7")); 58 | EXPECT_DEATH_IF_SUPPORTED(CPPGC_CHECK(5 == 7), 59 | ContainsRegex("failed.*5 == 7")); 60 | } 61 | 62 | #if CPPGC_SUPPORTS_SOURCE_LOCATION 63 | TEST(LoggingTest, SourceLocation) { 64 | using ::testing::AllOf; 65 | using ::testing::HasSubstr; 66 | // clang-format off 67 | constexpr auto loc = SourceLocation::Current(); 68 | EXPECT_DEATH_IF_SUPPORTED(CPPGC_DCHECK(false), AllOf(HasSubstr(loc.FileName()), HasSubstr(std::to_string(loc.Line() + 1)))); // NOLINT(whitespace/line_length) 69 | EXPECT_DEATH_IF_SUPPORTED(CPPGC_CHECK(false), AllOf(HasSubstr(loc.FileName()), HasSubstr(std::to_string(loc.Line() + 2)))); // NOLINT(whitespace/line_length) 70 | // clang-format on 71 | } 72 | #endif // CPPGC_SUPPORTS_SOURCE_LOCATION 73 | 74 | #endif // DEBUG 75 | 76 | } // namespace internal 77 | } // namespace cppgc 78 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/object-size-trait-unittest.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/object-size-trait.h" 6 | 7 | #include "include/cppgc/allocation.h" 8 | #include "include/cppgc/garbage-collected.h" 9 | #include "src/heap/cppgc/heap.h" 10 | #include "test/unittests/heap/cppgc/tests.h" 11 | #include 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | namespace { 17 | 18 | class ObjectSizeTraitTest : public testing::TestWithHeap {}; 19 | 20 | class GCed : public GarbageCollected { 21 | public: 22 | void Trace(Visitor*) const {} 23 | }; 24 | 25 | class NotGCed {}; 26 | class Mixin : public GarbageCollectedMixin {}; 27 | class UnmanagedMixinWithDouble { 28 | protected: 29 | virtual void ForceVTable() {} 30 | }; 31 | class GCedWithMixin : public GarbageCollected, 32 | public UnmanagedMixinWithDouble, 33 | public Mixin {}; 34 | 35 | } // namespace 36 | 37 | TEST_F(ObjectSizeTraitTest, GarbageCollected) { 38 | auto* obj = cppgc::MakeGarbageCollected(GetAllocationHandle()); 39 | EXPECT_GE(subtle::ObjectSizeTrait::GetSize(*obj), sizeof(GCed)); 40 | } 41 | 42 | TEST_F(ObjectSizeTraitTest, GarbageCollectedMixin) { 43 | auto* obj = cppgc::MakeGarbageCollected(GetAllocationHandle()); 44 | Mixin& mixin = static_cast(*obj); 45 | EXPECT_NE(static_cast(&mixin), obj); 46 | EXPECT_GE(subtle::ObjectSizeTrait::GetSize(mixin), 47 | sizeof(GCedWithMixin)); 48 | } 49 | 50 | } // namespace internal 51 | } // namespace cppgc 52 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/platform-unittest.cc: -------------------------------------------------------------------------------- 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 | #include "src/heap/cppgc/platform.h" 6 | 7 | #include "src/base/logging.h" 8 | #include "src/base/page-allocator.h" 9 | #include 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | 14 | TEST(FatalOutOfMemoryHandlerDeathTest, DefaultHandlerCrashes) { 15 | FatalOutOfMemoryHandler handler; 16 | EXPECT_DEATH_IF_SUPPORTED(handler(), ""); 17 | } 18 | 19 | namespace { 20 | 21 | constexpr uintptr_t kHeapNeedle = 0x14; 22 | 23 | [[noreturn]] void CustomHandler(const std::string&, const SourceLocation&, 24 | HeapBase* heap) { 25 | if (heap == reinterpret_cast(kHeapNeedle)) { 26 | FATAL("cust0m h4ndl3r with matching heap"); 27 | } 28 | FATAL("cust0m h4ndl3r"); 29 | } 30 | 31 | } // namespace 32 | 33 | TEST(FatalOutOfMemoryHandlerDeathTest, CustomHandlerCrashes) { 34 | FatalOutOfMemoryHandler handler; 35 | handler.SetCustomHandler(&CustomHandler); 36 | EXPECT_DEATH_IF_SUPPORTED(handler(), "cust0m h4ndl3r"); 37 | } 38 | 39 | TEST(FatalOutOfMemoryHandlerDeathTest, CustomHandlerWithHeapState) { 40 | FatalOutOfMemoryHandler handler(reinterpret_cast(kHeapNeedle)); 41 | handler.SetCustomHandler(&CustomHandler); 42 | EXPECT_DEATH_IF_SUPPORTED(handler(), "cust0m h4ndl3r with matching heap"); 43 | } 44 | 45 | } // namespace internal 46 | } // namespace cppgc 47 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/run-all-unittests.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/platform.h" 6 | #include "src/base/page-allocator.h" 7 | #include "test/unittests/heap/cppgc/test-platform.h" 8 | #include 9 | 10 | namespace { 11 | 12 | class CppGCEnvironment final : public ::testing::Environment { 13 | public: 14 | void SetUp() override { 15 | // Initialize the process for cppgc with an arbitrary page allocator. This 16 | // has to survive as long as the process, so it's ok to leak the allocator 17 | // here. 18 | cppgc::InitializeProcess(new v8::base::PageAllocator()); 19 | } 20 | 21 | void TearDown() override { cppgc::ShutdownProcess(); } 22 | }; 23 | 24 | } // namespace 25 | 26 | int main(int argc, char** argv) { 27 | // Don't catch SEH exceptions and continue as the following tests might hang 28 | // in an broken environment on windows. 29 | testing::GTEST_FLAG(catch_exceptions) = false; 30 | 31 | // Most unit-tests are multi-threaded, so enable thread-safe death-tests. 32 | testing::FLAGS_gtest_death_test_style = "threadsafe"; 33 | 34 | testing::InitGoogleMock(&argc, argv); 35 | testing::AddGlobalTestEnvironment(new CppGCEnvironment); 36 | return RUN_ALL_TESTS(); 37 | } 38 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/sanitizer-unittest.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/allocation.h" 6 | #include "src/base/macros.h" 7 | #include "src/base/sanitizer/asan.h" 8 | #include "test/unittests/heap/cppgc/tests.h" 9 | #include 10 | 11 | #if defined(LEAK_SANITIZER) 12 | #include 13 | #endif // LEAK_SANITIZER 14 | 15 | namespace cppgc { 16 | namespace internal { 17 | 18 | #if defined(LEAK_SANITIZER) 19 | 20 | using LsanTest = testing::TestWithHeap; 21 | 22 | class GCed final : public GarbageCollected { 23 | public: 24 | void Trace(cppgc::Visitor*) const {} 25 | std::unique_ptr dummy{std::make_unique(17)}; 26 | }; 27 | 28 | TEST_F(LsanTest, LeakDetectionDoesNotFindMemoryRetainedFromManaged) { 29 | auto* o = MakeGarbageCollected(GetAllocationHandle()); 30 | __lsan_do_leak_check(); 31 | USE(o); 32 | } 33 | 34 | #endif // LEAK_SANITIZER 35 | 36 | #ifdef V8_USE_ADDRESS_SANITIZER 37 | 38 | using AsanTest = testing::TestWithHeap; 39 | 40 | class ObjectPoisoningInDestructor final 41 | : public GarbageCollected { 42 | public: 43 | ~ObjectPoisoningInDestructor() { 44 | ASAN_POISON_MEMORY_REGION(this, sizeof(ObjectPoisoningInDestructor)); 45 | } 46 | void Trace(cppgc::Visitor*) const {} 47 | 48 | void* dummy{0}; 49 | }; 50 | 51 | TEST_F(AsanTest, ObjectPoisoningInDestructor) { 52 | MakeGarbageCollected(GetAllocationHandle()); 53 | PreciseGC(); 54 | } 55 | 56 | #endif // V8_USE_ADDRESS_SANITIZER 57 | 58 | } // namespace internal 59 | } // namespace cppgc 60 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/source-location-unittest.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/source-location.h" 6 | 7 | #include "src/base/macros.h" 8 | #include 9 | 10 | namespace cppgc { 11 | namespace internal { 12 | 13 | namespace { 14 | constexpr char kFileName[] = "source-location-unittest.cc"; 15 | 16 | bool Contains(const std::string& base_string, const std::string& substring) { 17 | return base_string.find(substring) != std::string::npos; 18 | } 19 | 20 | } // namespace 21 | 22 | TEST(SourceLocationTest, DefaultCtor) { 23 | constexpr SourceLocation loc; 24 | EXPECT_EQ(nullptr, loc.Function()); 25 | EXPECT_EQ(nullptr, loc.FileName()); 26 | EXPECT_EQ(0u, loc.Line()); 27 | } 28 | 29 | void TestSourceLocationCurrent() { 30 | static constexpr char kFunctionName[] = "TestSourceLocationCurrent"; 31 | static constexpr size_t kNextLine = __LINE__ + 1; 32 | constexpr auto loc = SourceLocation::Current(); 33 | #if !CPPGC_SUPPORTS_SOURCE_LOCATION 34 | EXPECT_EQ(nullptr, loc.Function()); 35 | EXPECT_EQ(nullptr, loc.FileName()); 36 | EXPECT_EQ(0u, loc.Line()); 37 | USE(kNextLine); 38 | return; 39 | #endif 40 | EXPECT_EQ(kNextLine, loc.Line()); 41 | EXPECT_TRUE(Contains(loc.FileName(), kFileName)); 42 | EXPECT_TRUE(Contains(loc.Function(), kFunctionName)); 43 | } 44 | 45 | TEST(SourceLocationTest, Current) { TestSourceLocationCurrent(); } 46 | 47 | void TestToString() { 48 | static const std::string kDescriptor = std::string(__func__) + "@" + 49 | __FILE__ + ":" + 50 | std::to_string(__LINE__ + 1); 51 | constexpr auto loc = SourceLocation::Current(); 52 | const auto string = loc.ToString(); 53 | EXPECT_EQ(kDescriptor, string); 54 | } 55 | 56 | #if CPPGC_SUPPORTS_SOURCE_LOCATION 57 | TEST(SourceLocationTest, ToString) { TestToString(); } 58 | #endif 59 | 60 | } // namespace internal 61 | } // namespace cppgc 62 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/test-platform.cc: -------------------------------------------------------------------------------- 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 | #include "test/unittests/heap/cppgc/test-platform.h" 6 | 7 | #include "include/libplatform/libplatform.h" 8 | #include "src/base/platform/platform.h" 9 | #include "src/base/platform/time.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | namespace testing { 14 | 15 | TestPlatform::TestPlatform( 16 | std::unique_ptr tracing_controller) 17 | : DefaultPlatform(0 /* thread_pool_size */, IdleTaskSupport::kEnabled, 18 | std::move(tracing_controller)) {} 19 | 20 | std::unique_ptr TestPlatform::PostJob( 21 | cppgc::TaskPriority priority, std::unique_ptr job_task) { 22 | if (AreBackgroundTasksDisabled()) return nullptr; 23 | return v8_platform_->PostJob(priority, std::move(job_task)); 24 | } 25 | 26 | void TestPlatform::RunAllForegroundTasks() { 27 | v8::platform::PumpMessageLoop(v8_platform_.get(), kNoIsolate); 28 | if (GetForegroundTaskRunner()->IdleTasksEnabled()) { 29 | v8::platform::RunIdleTasks(v8_platform_.get(), kNoIsolate, 30 | std::numeric_limits::max()); 31 | } 32 | } 33 | 34 | TestPlatform::DisableBackgroundTasksScope::DisableBackgroundTasksScope( 35 | TestPlatform* platform) 36 | : platform_(platform) { 37 | ++platform_->disabled_background_tasks_; 38 | } 39 | 40 | TestPlatform::DisableBackgroundTasksScope::~DisableBackgroundTasksScope() 41 | V8_NOEXCEPT { 42 | --platform_->disabled_background_tasks_; 43 | } 44 | 45 | } // namespace testing 46 | } // namespace internal 47 | } // namespace cppgc 48 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/test-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 V8_UNITTESTS_HEAP_CPPGC_TEST_PLATFORM_H_ 6 | #define V8_UNITTESTS_HEAP_CPPGC_TEST_PLATFORM_H_ 7 | 8 | #include "include/cppgc/default-platform.h" 9 | #include "src/base/compiler-specific.h" 10 | 11 | namespace cppgc { 12 | namespace internal { 13 | namespace testing { 14 | 15 | class TestPlatform : public DefaultPlatform { 16 | public: 17 | class V8_NODISCARD DisableBackgroundTasksScope { 18 | public: 19 | explicit DisableBackgroundTasksScope(TestPlatform*); 20 | ~DisableBackgroundTasksScope() V8_NOEXCEPT; 21 | 22 | private: 23 | TestPlatform* platform_; 24 | }; 25 | 26 | TestPlatform( 27 | std::unique_ptr tracing_controller = nullptr); 28 | 29 | std::unique_ptr PostJob( 30 | cppgc::TaskPriority priority, 31 | std::unique_ptr job_task) final; 32 | 33 | void RunAllForegroundTasks(); 34 | 35 | private: 36 | bool AreBackgroundTasksDisabled() const { 37 | return disabled_background_tasks_ > 0; 38 | } 39 | 40 | size_t disabled_background_tasks_ = 0; 41 | }; 42 | 43 | } // namespace testing 44 | } // namespace internal 45 | } // namespace cppgc 46 | 47 | #endif // V8_UNITTESTS_HEAP_CPPGC_TEST_PLATFORM_H_ 48 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/testing-unittest.cc: -------------------------------------------------------------------------------- 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 | #include "include/cppgc/testing.h" 6 | 7 | #include "include/cppgc/allocation.h" 8 | #include "include/cppgc/garbage-collected.h" 9 | #include "include/cppgc/persistent.h" 10 | #include "test/unittests/heap/cppgc/tests.h" 11 | #include 12 | 13 | namespace cppgc { 14 | namespace internal { 15 | 16 | namespace { 17 | class TestingTest : public testing::TestWithHeap {}; 18 | 19 | class GCed : public GarbageCollected { 20 | public: 21 | void Trace(Visitor*) const {} 22 | }; 23 | } // namespace 24 | 25 | TEST_F(TestingTest, 26 | OverrideEmbeddertackStateScopeDoesNotOverrideExplicitCalls) { 27 | { 28 | auto* gced = MakeGarbageCollected(GetHeap()->GetAllocationHandle()); 29 | WeakPersistent weak{gced}; 30 | internal::Heap::From(GetHeap())->CollectGarbage( 31 | GCConfig::PreciseAtomicConfig()); 32 | EXPECT_FALSE(weak); 33 | } 34 | { 35 | auto* gced = MakeGarbageCollected(GetHeap()->GetAllocationHandle()); 36 | WeakPersistent weak{gced}; 37 | cppgc::testing::OverrideEmbedderStackStateScope override_stack( 38 | GetHeap()->GetHeapHandle(), 39 | EmbedderStackState::kMayContainHeapPointers); 40 | internal::Heap::From(GetHeap())->CollectGarbage( 41 | GCConfig::PreciseAtomicConfig()); 42 | EXPECT_FALSE(weak); 43 | } 44 | { 45 | auto* gced = MakeGarbageCollected(GetHeap()->GetAllocationHandle()); 46 | WeakPersistent weak{gced}; 47 | cppgc::testing::OverrideEmbedderStackStateScope override_stack( 48 | GetHeap()->GetHeapHandle(), EmbedderStackState::kNoHeapPointers); 49 | internal::Heap::From(GetHeap())->CollectGarbage( 50 | GCConfig::ConservativeAtomicConfig()); 51 | EXPECT_TRUE(weak); 52 | } 53 | } 54 | 55 | TEST_F(TestingTest, StandaloneTestingHeap) { 56 | // Perform garbage collection through the StandaloneTestingHeap API. 57 | cppgc::testing::StandaloneTestingHeap heap(GetHeap()->GetHeapHandle()); 58 | heap.StartGarbageCollection(); 59 | heap.PerformMarkingStep(EmbedderStackState::kNoHeapPointers); 60 | heap.FinalizeGarbageCollection(EmbedderStackState::kNoHeapPointers); 61 | } 62 | 63 | } // namespace internal 64 | } // namespace cppgc 65 | -------------------------------------------------------------------------------- /test/unittests/heap/cppgc/tests.cc: -------------------------------------------------------------------------------- 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 | #include "test/unittests/heap/cppgc/tests.h" 6 | 7 | #include 8 | 9 | #include "src/heap/cppgc/object-allocator.h" 10 | #include "test/unittests/heap/cppgc/test-platform.h" 11 | 12 | #if !CPPGC_IS_STANDALONE 13 | #include "include/v8-initialization.h" 14 | #endif // !CPPGC_IS_STANDALONE 15 | 16 | namespace cppgc { 17 | namespace internal { 18 | namespace testing { 19 | 20 | // static 21 | std::shared_ptr TestWithPlatform::platform_; 22 | 23 | // static 24 | void TestWithPlatform::SetUpTestSuite() { 25 | platform_ = std::make_shared( 26 | std::make_unique()); 27 | 28 | #if !CPPGC_IS_STANDALONE 29 | // For non-standalone builds, we need to initialize V8's platform so that it 30 | // can be looked-up by trace-event.h. 31 | v8::V8::InitializePlatform(platform_->GetV8Platform()); 32 | v8::V8::Initialize(); 33 | #endif // !CPPGC_IS_STANDALONE 34 | } 35 | 36 | // static 37 | void TestWithPlatform::TearDownTestSuite() { 38 | #if !CPPGC_IS_STANDALONE 39 | v8::V8::Dispose(); 40 | v8::V8::DisposePlatform(); 41 | #endif // !CPPGC_IS_STANDALONE 42 | platform_.reset(); 43 | } 44 | 45 | TestWithHeap::TestWithHeap() 46 | : heap_(Heap::Create(platform_)), 47 | allocation_handle_(heap_->GetAllocationHandle()) {} 48 | 49 | TestWithHeap::~TestWithHeap() = default; 50 | 51 | void TestWithHeap::ResetLinearAllocationBuffers() { 52 | Heap::From(GetHeap())->object_allocator().ResetLinearAllocationBuffers(); 53 | } 54 | 55 | TestSupportingAllocationOnly::TestSupportingAllocationOnly() 56 | : no_gc_scope_(GetHeap()->GetHeapHandle()) {} 57 | 58 | } // namespace testing 59 | } // namespace internal 60 | } // namespace cppgc 61 | -------------------------------------------------------------------------------- /testing/OWNERS: -------------------------------------------------------------------------------- 1 | file:../INFRA_OWNERS 2 | -------------------------------------------------------------------------------- /testing/gmock/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2014 The Chromium 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 | # The file/directory layout of Google Test is not yet considered stable. Until 6 | # it stabilizes, Chromium code MUST use this target instead of reaching directly 7 | # into //third_party/googletest. 8 | 9 | import("//build_overrides/build.gni") 10 | 11 | source_set("gmock") { 12 | testonly = true 13 | sources = [ 14 | "include/gmock/gmock-actions.h", 15 | "include/gmock/gmock-matchers.h", 16 | "include/gmock/gmock.h", 17 | ] 18 | public_deps = [ "//third_party/googletest:gmock" ] 19 | } 20 | 21 | # The file/directory layout of Google Test is not yet considered stable. Until 22 | # it stabilizes, Chromium code MUST use this target instead of reaching directly 23 | # into //third_party/googletest. 24 | source_set("gmock_main") { 25 | testonly = true 26 | deps = [ "//third_party/googletest:gmock_main" ] 27 | } 28 | -------------------------------------------------------------------------------- /testing/gmock/OWNERS: -------------------------------------------------------------------------------- 1 | thakis@chromium.org 2 | pwnall@chromium.org 3 | -------------------------------------------------------------------------------- /testing/gmock/include/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | '+third_party/googletest/src/googlemock/include/gmock', 3 | ] 4 | -------------------------------------------------------------------------------- /testing/gmock/include/gmock/gmock-actions.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googlemock/include/gmock/gmock-actions.h" 11 | -------------------------------------------------------------------------------- /testing/gmock/include/gmock/gmock-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googlemock/include/gmock/gmock-matchers.h" 11 | -------------------------------------------------------------------------------- /testing/gmock/include/gmock/gmock.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googlemock/include/gmock/gmock.h" 11 | -------------------------------------------------------------------------------- /testing/gtest-support.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_TESTING_GTEST_SUPPORT_H_ 6 | #define V8_TESTING_GTEST_SUPPORT_H_ 7 | 8 | #include "testing/gtest/include/gtest/gtest.h" 9 | 10 | namespace testing { 11 | namespace internal { 12 | 13 | #define GET_TYPE_NAME(type) \ 14 | template <> \ 15 | inline std::string GetTypeName() { \ 16 | return #type; \ 17 | } 18 | GET_TYPE_NAME(bool) 19 | GET_TYPE_NAME(signed char) 20 | GET_TYPE_NAME(unsigned char) 21 | GET_TYPE_NAME(short) 22 | GET_TYPE_NAME(unsigned short) 23 | GET_TYPE_NAME(int) 24 | GET_TYPE_NAME(unsigned int) 25 | GET_TYPE_NAME(long) 26 | GET_TYPE_NAME(unsigned long) 27 | GET_TYPE_NAME(long long) 28 | GET_TYPE_NAME(unsigned long long) 29 | GET_TYPE_NAME(float) 30 | GET_TYPE_NAME(double) 31 | #undef GET_TYPE_NAME 32 | 33 | 34 | // TRACED_FOREACH(type, var, container) expands to a loop that assigns |var| 35 | // every item in the |container| and adds a SCOPED_TRACE() message for the 36 | // |var| while inside the loop body. 37 | #define TRACED_FOREACH(_type, _var, _container) \ 38 | for (_type const _var : _container) \ 39 | for (bool _var##_done = false; !_var##_done;) \ 40 | for (SCOPED_TRACE(::testing::Message() << #_var << " = " << _var); \ 41 | !_var##_done; _var##_done = true) 42 | 43 | // TRACED_FORRANGE(type, var, low, high) expands to a loop that assigns |var| 44 | // every value in the range |low| to (including) |high| and adds a 45 | // SCOPED_TRACE() message for the |var| while inside the loop body. 46 | // TODO(bmeurer): Migrate to C++11 once we're ready. 47 | #define TRACED_FORRANGE(_type, _var, _low, _high) \ 48 | for (_type _var##_i = _low; _var##_i <= _high; ++_var##_i) \ 49 | for (bool _var##_done = false; !_var##_done;) \ 50 | for (_type const _var = _var##_i; !_var##_done;) \ 51 | for (SCOPED_TRACE(::testing::Message() << #_var << " = " << _var); \ 52 | !_var##_done; _var##_done = true) 53 | 54 | } // namespace internal 55 | } // namespace testing 56 | 57 | #endif // V8_TESTING_GTEST_SUPPORT_H_ 58 | -------------------------------------------------------------------------------- /testing/gtest/OWNERS: -------------------------------------------------------------------------------- 1 | thakis@chromium.org 2 | pwnall@chromium.org 3 | -------------------------------------------------------------------------------- /testing/gtest/empty.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Chromium 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 | -------------------------------------------------------------------------------- /testing/gtest/include/DEPS: -------------------------------------------------------------------------------- 1 | include_rules = [ 2 | '+third_party/googletest/src/googletest/include/gtest', 3 | ] 4 | -------------------------------------------------------------------------------- /testing/gtest/include/gtest/gtest-death-test.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googletest/include/gtest/gtest-death-test.h" 11 | -------------------------------------------------------------------------------- /testing/gtest/include/gtest/gtest-message.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googletest/include/gtest/gtest-message.h" 11 | -------------------------------------------------------------------------------- /testing/gtest/include/gtest/gtest-param-test.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googletest/include/gtest/gtest-param-test.h" 11 | -------------------------------------------------------------------------------- /testing/gtest/include/gtest/gtest-spi.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googletest/include/gtest/gtest-spi.h" 11 | -------------------------------------------------------------------------------- /testing/gtest/include/gtest/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #include "third_party/googletest/src/googletest/include/gtest/gtest.h" 11 | -------------------------------------------------------------------------------- /testing/gtest/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Chromium 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 | // The file/directory layout of Google Test is not yet considered stable. Until 6 | // it stabilizes, Chromium code will use forwarding headers in testing/gtest 7 | // and testing/gmock, instead of directly including files in 8 | // third_party/googletest. 9 | 10 | #if !defined(GOOGLE3) 11 | #include "third_party/googletest/src/googletest/include/gtest/gtest_prod.h" 12 | #endif --------------------------------------------------------------------------------