Permalink
Browse files

deps: back-port b049d1a from V8 upstream

Original commit message:

    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}

PR-URL: #11204
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information...
bnoordhuis authored and italoacasas committed Feb 6, 2017
1 parent ae39dcb commit 20127e0c0ac97968ef0104d19ffdcc5545dc98d5
View
@@ -58,15 +58,7 @@ Zone::~Zone() {
void* Zone::New(size_t size) {
// Round up the requested size to fit the alignment.
size = RoundUp(size, kAlignment);
// 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);
}
size = RoundUp(size, kAlignmentInBytes);
// Check if the requested size is available without expanding.
Address result = position_;
@@ -86,7 +78,7 @@ void* Zone::New(size_t size) {
ASAN_POISON_MEMORY_REGION(redzone_position, kASanRedzoneBytes);
// Check that the result has the proper alignment and return it.
DCHECK(IsAddressAligned(result, kAlignment, 0));
DCHECK(IsAddressAligned(result, kAlignmentInBytes, 0));
allocation_size_ += size;
return reinterpret_cast<void*>(result);
}
@@ -121,7 +113,7 @@ void Zone::DeleteAll() {
// force a new segment to be allocated on demand.
if (keep) {
Address start = keep->start();
position_ = RoundUp(start, kAlignment);
position_ = RoundUp(start, kAlignmentInBytes);
limit_ = keep->end();
// Un-poison so we can re-use the segment later.
ASAN_UNPOISON_MEMORY_REGION(start, keep->capacity());
@@ -167,7 +159,7 @@ Segment* Zone::NewSegment(size_t size) {
Address Zone::NewExpand(size_t size) {
// Make sure the requested size is already properly aligned and that
// 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_ ||
reinterpret_cast<uintptr_t>(limit_) -
reinterpret_cast<uintptr_t>(position_) <
@@ -179,7 +171,7 @@ Address Zone::NewExpand(size_t size) {
// is to avoid excessive malloc() and free() overhead.
Segment* head = segment_head_;
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);
size_t new_size = kSegmentOverhead + new_size_no_overhead;
const size_t min_new_size = kSegmentOverhead + size;
@@ -208,7 +200,7 @@ Address Zone::NewExpand(size_t size) {
}
// Recompute 'top' and 'limit' based on the new segment.
Address result = RoundUp(segment->start(), kAlignment);
Address result = RoundUp(segment->start(), kAlignmentInBytes);
position_ = result + size;
// Check for address overflow.
// (Should not happen since the segment is guaranteed to accomodate
View
@@ -63,15 +63,8 @@ class V8_EXPORT_PRIVATE Zone final {
AccountingAllocator* allocator() const { return allocator_; }
private:
// All pointers returned from New() have this alignment. In addition, if the
// object being allocated has a size that is divisible by 8 then its alignment
// will be 8. ASan requires 8-byte alignment.
#ifdef V8_USE_ADDRESS_SANITIZER
static const size_t kAlignment = 8;
STATIC_ASSERT(kPointerSize <= 8);
#else
static const size_t kAlignment = kPointerSize;
#endif
// All pointers returned from New() are 8-byte aligned.
static const size_t kAlignmentInBytes = 8;
// Never allocate segments smaller than this size in bytes.
static const size_t kMinimumSegmentSize = 8 * KB;
@@ -105,7 +98,7 @@ class V8_EXPORT_PRIVATE Zone final {
// The free region in the current (front) segment is represented as
// the half-open interval [position, limit). The 'position' variable
// is guaranteed to be aligned as dictated by kAlignment.
// is guaranteed to be aligned as dictated by kAlignmentInBytes.
Address position_;
Address limit_;
@@ -128,6 +128,7 @@ v8_executable("unittests") {
"wasm/switch-logic-unittest.cc",
"wasm/wasm-macro-gen-unittest.cc",
"wasm/wasm-module-builder-unittest.cc",
"zone/zone-unittest.cc",
]
if (v8_current_cpu == "arm") {
@@ -116,6 +116,7 @@
'test-utils.h',
'test-utils.cc',
'value-serializer-unittest.cc',
'zone/zone-unittest.cc',
'wasm/asm-types-unittest.cc',
'wasm/ast-decoder-unittest.cc',
'wasm/control-transfer-unittest.cc',
@@ -0,0 +1,23 @@
// 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);
for (size_t i = 0; i < 16; ++i) {
ASSERT_EQ(reinterpret_cast<intptr_t>(zone.New(i)) % 8, 0);
}
}
} // namespace internal
} // namespace v8

0 comments on commit 20127e0

Please sign in to comment.