Commit b049d1a5 authored by jochen's avatar jochen Committed by Commit bot

Ensure we align zone memory at 8 byte boundaries on all platforms

BUG=v8:5668
R=verwaest@chromium.org

Review-Url: https://codereview.chromium.org/2672203002
Cr-Commit-Position: refs/heads/master@{#42959}
parent 8f2245bf
...@@ -63,15 +63,7 @@ Zone::~Zone() { ...@@ -63,15 +63,7 @@ Zone::~Zone() {
void* Zone::New(size_t size) { void* Zone::New(size_t size) {
// Round up the requested size to fit the alignment. // Round up the requested size to fit the alignment.
size = RoundUp(size, kAlignment); size = RoundUp(size, kAlignmentInBytes);
// If the allocation size is divisible by 8 then we return an 8-byte aligned
// address.
if (kPointerSize == 4 && kAlignment == 4) {
position_ += ((~size) & 4) & (reinterpret_cast<intptr_t>(position_) & 4);
} else {
DCHECK(kAlignment >= kPointerSize);
}
// Check if the requested size is available without expanding. // Check if the requested size is available without expanding.
Address result = position_; Address result = position_;
...@@ -91,7 +83,7 @@ void* Zone::New(size_t size) { ...@@ -91,7 +83,7 @@ void* Zone::New(size_t size) {
ASAN_POISON_MEMORY_REGION(redzone_position, kASanRedzoneBytes); ASAN_POISON_MEMORY_REGION(redzone_position, kASanRedzoneBytes);
// Check that the result has the proper alignment and return it. // Check that the result has the proper alignment and return it.
DCHECK(IsAddressAligned(result, kAlignment, 0)); DCHECK(IsAddressAligned(result, kAlignmentInBytes, 0));
allocation_size_ += size; allocation_size_ += size;
return reinterpret_cast<void*>(result); return reinterpret_cast<void*>(result);
} }
...@@ -132,7 +124,7 @@ Segment* Zone::NewSegment(size_t requested_size) { ...@@ -132,7 +124,7 @@ Segment* Zone::NewSegment(size_t requested_size) {
Address Zone::NewExpand(size_t size) { Address Zone::NewExpand(size_t size) {
// Make sure the requested size is already properly aligned and that // Make sure the requested size is already properly aligned and that
// there isn't enough room in the Zone to satisfy the request. // there isn't enough room in the Zone to satisfy the request.
DCHECK_EQ(size, RoundDown(size, kAlignment)); DCHECK_EQ(size, RoundDown(size, kAlignmentInBytes));
DCHECK(limit_ < position_ || DCHECK(limit_ < position_ ||
reinterpret_cast<uintptr_t>(limit_) - reinterpret_cast<uintptr_t>(limit_) -
reinterpret_cast<uintptr_t>(position_) < reinterpret_cast<uintptr_t>(position_) <
...@@ -144,7 +136,7 @@ Address Zone::NewExpand(size_t size) { ...@@ -144,7 +136,7 @@ Address Zone::NewExpand(size_t size) {
// is to avoid excessive malloc() and free() overhead. // is to avoid excessive malloc() and free() overhead.
Segment* head = segment_head_; Segment* head = segment_head_;
const size_t old_size = (head == nullptr) ? 0 : head->size(); const size_t old_size = (head == nullptr) ? 0 : head->size();
static const size_t kSegmentOverhead = sizeof(Segment) + kAlignment; static const size_t kSegmentOverhead = sizeof(Segment) + kAlignmentInBytes;
const size_t new_size_no_overhead = size + (old_size << 1); const size_t new_size_no_overhead = size + (old_size << 1);
size_t new_size = kSegmentOverhead + new_size_no_overhead; size_t new_size = kSegmentOverhead + new_size_no_overhead;
const size_t min_new_size = kSegmentOverhead + size; const size_t min_new_size = kSegmentOverhead + size;
...@@ -173,7 +165,7 @@ Address Zone::NewExpand(size_t size) { ...@@ -173,7 +165,7 @@ Address Zone::NewExpand(size_t size) {
} }
// Recompute 'top' and 'limit' based on the new segment. // Recompute 'top' and 'limit' based on the new segment.
Address result = RoundUp(segment->start(), kAlignment); Address result = RoundUp(segment->start(), kAlignmentInBytes);
position_ = result + size; position_ = result + size;
// Check for address overflow. // Check for address overflow.
// (Should not happen since the segment is guaranteed to accomodate // (Should not happen since the segment is guaranteed to accomodate
......
...@@ -63,16 +63,8 @@ class V8_EXPORT_PRIVATE Zone final { ...@@ -63,16 +63,8 @@ class V8_EXPORT_PRIVATE Zone final {
AccountingAllocator* allocator() const { return allocator_; } AccountingAllocator* allocator() const { return allocator_; }
private: private:
// All pointers returned from New() have this alignment. In addition, if the // All pointers returned from New() are 8-byte aligned.
// object being allocated has a size that is divisible by 8 then its alignment static const size_t kAlignmentInBytes = 8;
// will be 8. ASan requires 8-byte alignment. MIPS also requires 8-byte
// alignment.
#if defined(V8_USE_ADDRESS_SANITIZER) || defined(V8_TARGET_ARCH_MIPS)
static const size_t kAlignment = 8;
STATIC_ASSERT(kPointerSize <= 8);
#else
static const size_t kAlignment = kPointerSize;
#endif
// Never allocate segments smaller than this size in bytes. // Never allocate segments smaller than this size in bytes.
static const size_t kMinimumSegmentSize = 8 * KB; static const size_t kMinimumSegmentSize = 8 * KB;
......
...@@ -143,6 +143,7 @@ v8_executable("unittests") { ...@@ -143,6 +143,7 @@ v8_executable("unittests") {
"wasm/wasm-opcodes-unittest.cc", "wasm/wasm-opcodes-unittest.cc",
"zone/segmentpool-unittest.cc", "zone/segmentpool-unittest.cc",
"zone/zone-chunk-list-unittest.cc", "zone/zone-chunk-list-unittest.cc",
"zone/zone-unittest.cc",
] ]
if (v8_current_cpu == "arm") { if (v8_current_cpu == "arm") {
......
...@@ -130,6 +130,7 @@ ...@@ -130,6 +130,7 @@
'value-serializer-unittest.cc', 'value-serializer-unittest.cc',
'zone/segmentpool-unittest.cc', 'zone/segmentpool-unittest.cc',
'zone/zone-chunk-list-unittest.cc', 'zone/zone-chunk-list-unittest.cc',
'zone/zone-unittest.cc',
'wasm/asm-types-unittest.cc', 'wasm/asm-types-unittest.cc',
'wasm/control-transfer-unittest.cc', 'wasm/control-transfer-unittest.cc',
'wasm/decoder-unittest.cc', 'wasm/decoder-unittest.cc',
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/zone/zone.h"
#include "src/zone/accounting-allocator.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
TEST(Zone, 8ByteAlignment) {
AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
for (size_t i = 0; i < 16; ++i) {
ASSERT_EQ(reinterpret_cast<intptr_t>(zone.New(i)) % 8, 0);
}
}
} // namespace internal
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment