cppgc: Replace memory model macros with proper functions

Bug: chromium:1056170
Change-Id: I41ebc2e507d1662588364396f1129c75a0f0841d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2851890
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74233}
This commit is contained in:
Michael Lippautz 2021-04-27 14:20:14 +02:00 committed by Commit Bot
parent 87043bbb96
commit bd916e69af
12 changed files with 97 additions and 72 deletions

View File

@ -4875,7 +4875,6 @@ v8_source_set("v8_cppgc_shared") {
"src/heap/base/stack.h",
"src/heap/base/worklist.cc",
"src/heap/base/worklist.h",
"src/heap/cppgc/sanitizers.h",
]
if (is_clang || !is_win) {
@ -5022,6 +5021,7 @@ v8_source_set("cppgc_base") {
"src/heap/cppgc/marking-visitor.h",
"src/heap/cppgc/marking-worklists.cc",
"src/heap/cppgc/marking-worklists.h",
"src/heap/cppgc/memory.h",
"src/heap/cppgc/metric-recorder.h",
"src/heap/cppgc/name-trait.cc",
"src/heap/cppgc/object-allocator.cc",

View File

@ -8,8 +8,9 @@
#include "src/base/macros.h"
#include "src/base/platform/platform.h"
#include "src/base/sanitizer/asan.h"
#include "src/base/sanitizer/msan.h"
#include "src/heap/cppgc/globals.h"
#include "src/heap/cppgc/sanitizers.h"
namespace heap {
namespace base {

View File

@ -15,6 +15,7 @@
#include "src/heap/cppgc/heap-base.h"
#include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/heap-space.h"
#include "src/heap/cppgc/memory.h"
#include "src/heap/cppgc/object-poisoner.h"
#include "src/heap/cppgc/raw-heap.h"
#include "src/heap/cppgc/stats-collector.h"
@ -275,7 +276,7 @@ class CompactionState final {
// Return remaining available pages to the free page pool, decommitting
// them from the pagefile.
for (NormalPage* page : available_pages_) {
SET_MEMORY_INACCESSIBLE(page->PayloadStart(), page->PayloadSize());
SetMemoryInaccessible(page->PayloadStart(), page->PayloadSize());
NormalPage::Destroy(page);
}
}
@ -303,7 +304,7 @@ class CompactionState final {
current_page_->PayloadSize() - used_bytes_in_current_page_;
Address payload = current_page_->PayloadStart();
Address free_start = payload + used_bytes_in_current_page_;
SET_MEMORY_INACCESSIBLE(free_start, freed_size);
SetMemoryInaccessible(free_start, freed_size);
space_->free_list().Add({free_start, freed_size});
current_page_->object_start_bitmap().SetBit(free_start);
}

View File

@ -9,7 +9,7 @@
#include "src/heap/cppgc/heap-base.h"
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/sanitizers.h"
#include "src/heap/cppgc/memory.h"
namespace cppgc {
namespace internal {
@ -52,7 +52,7 @@ void FreeUnreferencedObject(void* object) {
auto& normal_space = *static_cast<NormalPageSpace*>(base_page->space());
auto& lab = normal_space.linear_allocation_buffer();
ConstAddress payload_end = header.PayloadEnd();
SET_MEMORY_INACCESSIBLE(&header, header_size);
SetMemoryInaccessible(&header, header_size);
if (payload_end == lab.start()) { // Returning to LAB.
lab.Set(reinterpret_cast<Address>(&header), lab.size() + header_size);
normal_page->object_start_bitmap().ClearBit(lab.start());
@ -79,7 +79,7 @@ bool Grow(HeapObjectHeader& header, BasePage& base_page, size_t new_size,
// LABs are considered used memory which means that no allocated size
// adjustments are needed.
Address delta_start = lab.Allocate(size_delta);
SET_MEMORY_ACCESSIBLE(delta_start, size_delta);
SetMemoryAccessible(delta_start, size_delta);
header.SetSize(new_size);
return true;
}
@ -100,14 +100,14 @@ bool Shrink(HeapObjectHeader& header, BasePage& base_page, size_t new_size,
// LABs are considered used memory which means that no allocated size
// adjustments are needed.
lab.Set(free_start, lab.size() + size_delta);
SET_MEMORY_INACCESSIBLE(lab.start(), size_delta);
SetMemoryInaccessible(lab.start(), size_delta);
header.SetSize(new_size);
return true;
}
// Heuristic: Only return memory to the free list if the block is larger than
// the smallest size class.
if (size_delta >= ObjectAllocator::kSmallestSpaceSize) {
SET_MEMORY_INACCESSIBLE(free_start, size_delta);
SetMemoryInaccessible(free_start, size_delta);
base_page.heap()->stats_collector()->NotifyExplicitFree(size_delta);
normal_space.free_list().Add({free_start, size_delta});
NormalPage::From(&base_page)->object_start_bitmap().SetBit(free_start);

View File

@ -8,9 +8,9 @@
#include "include/cppgc/internal/logging.h"
#include "src/base/bits.h"
#include "src/base/sanitizer/asan.h"
#include "src/heap/cppgc/globals.h"
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/sanitizers.h"
namespace cppgc {
namespace internal {

View File

@ -6,9 +6,9 @@
#include "include/cppgc/internal/api-constants.h"
#include "src/base/macros.h"
#include "src/base/sanitizer/asan.h"
#include "src/heap/cppgc/gc-info-table.h"
#include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/sanitizers.h"
namespace cppgc {
namespace internal {

73
src/heap/cppgc/memory.h Normal file
View File

@ -0,0 +1,73 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_CPPGC_MEMORY_H_
#define V8_HEAP_CPPGC_MEMORY_H_
#include <cstddef>
#include <cstdint>
#include <cstring>
#include "src/base/macros.h"
#include "src/base/sanitizer/asan.h"
#include "src/base/sanitizer/msan.h"
namespace cppgc {
namespace internal {
inline void ZapMemory(void* address, size_t size) {
// The lowest bit of the zapped value should be 0 so that zapped object are
// never viewed as fully constructed objects.
static constexpr uint8_t kZappedValue = 0xdc;
memset(address, kZappedValue, size);
}
// Together `SetMemoryAccessible()` and `SetMemoryInaccessible()` form the
// memory access model for allocation and free.
V8_INLINE void SetMemoryAccessible(void* address, size_t size) {
#if defined(V8_USE_MEMORY_SANITIZER)
MSAN_MEMORY_IS_INITIALIZED(address, size);
#elif defined(V8_USE_ADDRESS_SANITIZER)
ASAN_UNPOISON_MEMORY_REGION(address, size);
#elif DEBUG
memset(address, 0, size);
#else // Release builds.
// Nothing to be done for release builds.
#endif // Release builds.
}
V8_INLINE void SetMemoryInaccessible(void* address, size_t size) {
#if defined(V8_USE_MEMORY_SANITIZER)
memset(address, 0, size);
MSAN_ALLOCATED_UNINITIALIZED_MEMORY(address, size);
#elif defined(V8_USE_ADDRESS_SANITIZER)
memset(address, 0, size);
ASAN_POISON_MEMORY_REGION(address, size);
#elif DEBUG
::cppgc::internal::ZapMemory(address, size);
#else // Release builds.
memset(address, 0, size);
#endif // Release builds.
}
} // namespace internal
} // namespace cppgc
#endif // V8_HEAP_CPPGC_MEMORY_H_

View File

@ -12,9 +12,9 @@
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/heap-space.h"
#include "src/heap/cppgc/memory.h"
#include "src/heap/cppgc/object-start-bitmap.h"
#include "src/heap/cppgc/raw-heap.h"
#include "src/heap/cppgc/sanitizers.h"
namespace cppgc {
@ -111,10 +111,10 @@ void* ObjectAllocator::AllocateObjectOnSpace(NormalPageSpace* space,
#if !defined(V8_USE_MEMORY_SANITIZER) && !defined(V8_USE_ADDRESS_SANITIZER) && \
DEBUG
// For debug builds, unzap only the payload.
SET_MEMORY_ACCESSIBLE(static_cast<char*>(raw) + sizeof(HeapObjectHeader),
size - sizeof(HeapObjectHeader));
SetMemoryAccessible(static_cast<char*>(raw) + sizeof(HeapObjectHeader),
size - sizeof(HeapObjectHeader));
#else
SET_MEMORY_ACCESSIBLE(raw, size);
SetMemoryAccessible(raw, size);
#endif
auto* header = new (raw) HeapObjectHeader(size, gcinfo);

View File

@ -5,10 +5,10 @@
#ifndef V8_HEAP_CPPGC_OBJECT_POISONER_H_
#define V8_HEAP_CPPGC_OBJECT_POISONER_H_
#include "src/base/sanitizer/asan.h"
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/heap-visitor.h"
#include "src/heap/cppgc/sanitizers.h"
namespace cppgc {
namespace internal {

View File

@ -5,7 +5,7 @@
#include "src/heap/cppgc/page-memory.h"
#include "src/base/macros.h"
#include "src/heap/cppgc/sanitizers.h"
#include "src/base/sanitizer/asan.h"
namespace cppgc {
namespace internal {

View File

@ -1,50 +0,0 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_CPPGC_SANITIZERS_H_
#define V8_HEAP_CPPGC_SANITIZERS_H_
#include <stdint.h>
#include <string.h>
#include "src/base/macros.h"
#include "src/base/sanitizer/asan.h"
#include "src/base/sanitizer/msan.h"
// API for newly allocated or reclaimed memory.
#if defined(V8_USE_MEMORY_SANITIZER)
#define SET_MEMORY_ACCESSIBLE(address, size) \
MSAN_MEMORY_IS_INITIALIZED(address, size);
#define SET_MEMORY_INACCESSIBLE(address, size) \
memset((address), 0, (size)); \
MSAN_ALLOCATED_UNINITIALIZED_MEMORY((address), (size))
#elif defined(V8_USE_ADDRESS_SANITIZER)
#define SET_MEMORY_ACCESSIBLE(address, size) \
ASAN_UNPOISON_MEMORY_REGION(address, size);
#define SET_MEMORY_INACCESSIBLE(address, size) \
memset((address), 0, (size)); \
ASAN_POISON_MEMORY_REGION(address, size)
#elif DEBUG
#define SET_MEMORY_ACCESSIBLE(address, size) memset((address), 0, (size))
#define SET_MEMORY_INACCESSIBLE(address, size) \
::cppgc::internal::ZapMemory((address), (size));
#else
#define SET_MEMORY_ACCESSIBLE(address, size) ((void)(address), (void)(size))
#define SET_MEMORY_INACCESSIBLE(address, size) memset((address), 0, (size))
#endif
namespace cppgc {
namespace internal {
inline void ZapMemory(void* address, size_t size) {
// The lowest bit of the zapped value should be 0 so that zapped object
// are never viewed as fully constructed objects.
static constexpr uint8_t kZappedValue = 0xdc;
memset(address, kZappedValue, size);
}
} // namespace internal
} // namespace cppgc
#endif // V8_HEAP_CPPGC_SANITIZERS_H_

View File

@ -18,10 +18,10 @@
#include "src/heap/cppgc/heap-page.h"
#include "src/heap/cppgc/heap-space.h"
#include "src/heap/cppgc/heap-visitor.h"
#include "src/heap/cppgc/memory.h"
#include "src/heap/cppgc/object-poisoner.h"
#include "src/heap/cppgc/object-start-bitmap.h"
#include "src/heap/cppgc/raw-heap.h"
#include "src/heap/cppgc/sanitizers.h"
#include "src/heap/cppgc/stats-collector.h"
#include "src/heap/cppgc/task-handle.h"
@ -133,7 +133,7 @@ class InlinedFinalizationBuilder final {
void AddFinalizer(HeapObjectHeader* header, size_t size) {
header->Finalize();
SET_MEMORY_INACCESSIBLE(header, size);
SetMemoryInaccessible(header, size);
}
void AddFreeListEntry(Address start, size_t size) {
@ -164,7 +164,7 @@ class DeferredFinalizationBuilder final {
// Unmarked memory may have been poisoned. In the non-concurrent case this
// is taken care of by finalizing a header.
ASAN_UNPOISON_MEMORY_REGION(header, size);
SET_MEMORY_INACCESSIBLE(header, size);
SetMemoryInaccessible(header, size);
}
}
@ -205,7 +205,7 @@ typename FinalizationBuilder::ResultType SweepNormalPage(NormalPage* page) {
const size_t size = header->GetSize();
// Check if this is a free list entry.
if (header->IsFree<kAtomicAccess>()) {
SET_MEMORY_INACCESSIBLE(header, std::min(kFreeListEntrySize, size));
SetMemoryInaccessible(header, std::min(kFreeListEntrySize, size));
begin += size;
continue;
}
@ -292,7 +292,7 @@ class SweepFinalizer final {
for (HeapObjectHeader* object : page_state->unfinalized_objects) {
const size_t size = object->GetSize();
object->Finalize();
SET_MEMORY_INACCESSIBLE(object, size);
SetMemoryInaccessible(object, size);
}
// Unmap page if empty.