Browse Source

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: https://github.com/nodejs/node/pull/11204
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
v6
Ben Noordhuis 8 years ago
parent
commit
039a813ff0
  1. 20
      deps/v8/src/zone/zone.cc
  2. 13
      deps/v8/src/zone/zone.h
  3. 1
      deps/v8/test/unittests/BUILD.gn
  4. 1
      deps/v8/test/unittests/unittests.gyp
  5. 23
      deps/v8/test/unittests/zone/zone-unittest.cc

20
deps/v8/src/zone/zone.cc

@ -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

13
deps/v8/src/zone/zone.h

@ -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_;

1
deps/v8/test/unittests/BUILD.gn

@ -129,6 +129,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") {

1
deps/v8/test/unittests/unittests.gyp

@ -117,6 +117,7 @@
'test-utils.cc',
'unicode-unittest.cc',
'value-serializer-unittest.cc',
'zone/zone-unittest.cc',
'wasm/asm-types-unittest.cc',
'wasm/ast-decoder-unittest.cc',
'wasm/control-transfer-unittest.cc',

23
deps/v8/test/unittests/zone/zone-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
Loading…
Cancel
Save