Commit 8a1e927f authored by tzik's avatar tzik Committed by Commit Bot

Update MicrotaskQueue ring buffer for pointer compression

This updates MicrotaskQueue to use pointer-compression style object
reference.

Bug: v8:8124
Change-Id: I7bef92a8760609f3045d2025b145b9a0ec880424
Reviewed-on: https://chromium-review.googlesource.com/c/1478320
Commit-Queue: Taiju Tsuiki <tzik@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59762}
parent 9b5fe7b2
......@@ -100,7 +100,7 @@ void MicrotaskQueueBuiltinsAssembler::SetMicrotaskQueueStart(
TNode<IntPtrT> MicrotaskQueueBuiltinsAssembler::CalculateRingBufferOffset(
TNode<IntPtrT> capacity, TNode<IntPtrT> start, TNode<IntPtrT> index) {
return TimesSystemPointerSize(
return TimesTaggedSize(
WordAnd(IntPtrAdd(start, index), IntPtrSub(capacity, IntPtrConstant(1))));
}
......@@ -482,9 +482,9 @@ TF_BUILTIN(EnqueueMicrotask, MicrotaskQueueBuiltinsAssembler) {
// |microtask_queue| has an unused slot to store |microtask|.
{
StoreNoWriteBarrier(MachineType::PointerRepresentation(), ring_buffer,
CalculateRingBufferOffset(capacity, start, size),
BitcastTaggedToWord(microtask));
StoreNoWriteBarrier(
MachineType::TaggedPointer().representation(), ring_buffer,
CalculateRingBufferOffset(capacity, start, size), microtask);
StoreNoWriteBarrier(MachineType::PointerRepresentation(), microtask_queue,
IntPtrConstant(MicrotaskQueue::kSizeOffset),
IntPtrAdd(size, IntPtrConstant(1)));
......@@ -528,9 +528,8 @@ TF_BUILTIN(RunMicrotasks, MicrotaskQueueBuiltinsAssembler) {
TNode<IntPtrT> offset =
CalculateRingBufferOffset(capacity, start, IntPtrConstant(0));
TNode<RawPtrT> microtask_pointer =
UncheckedCast<RawPtrT>(Load(MachineType::Pointer(), ring_buffer, offset));
TNode<Microtask> microtask = CAST(BitcastWordToTagged(microtask_pointer));
TNode<Microtask> microtask =
CAST(Load(MachineType::TaggedPointer(), ring_buffer, offset));
TNode<IntPtrT> new_size = IntPtrSub(size, IntPtrConstant(1));
TNode<IntPtrT> new_start = WordAnd(IntPtrAdd(start, IntPtrConstant(1)),
......
......@@ -64,7 +64,7 @@ MicrotaskQueue::~MicrotaskQueue() {
next_->prev_ = prev_;
prev_->next_ = next_;
}
delete[] ring_buffer_;
delete[] reinterpret_cast<Microtask*>(ring_buffer_.address());
}
// static
......@@ -86,7 +86,8 @@ void MicrotaskQueue::EnqueueMicrotask(Microtask microtask) {
}
DCHECK_LT(size_, capacity_);
ring_buffer_[(start_ + size_) % capacity_] = microtask.ptr();
(ring_buffer_ + static_cast<int>((start_ + size_) % capacity_))
.store(microtask);
++size_;
}
......@@ -141,8 +142,8 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
// If execution is terminating, clean up and propagate that to TryCatch scope.
if (maybe_result.is_null() && maybe_exception.is_null()) {
delete[] ring_buffer_;
ring_buffer_ = nullptr;
delete[] reinterpret_cast<Microtask*>(ring_buffer_.address());
ring_buffer_ = ObjectSlot();
capacity_ = 0;
size_ = 0;
start_ = 0;
......@@ -161,12 +162,12 @@ void MicrotaskQueue::IterateMicrotasks(RootVisitor* visitor) {
// Iterate pending Microtasks as root objects to avoid the write barrier for
// all single Microtask. If this hurts the GC performance, use a FixedArray.
visitor->VisitRootPointers(
Root::kStrongRoots, nullptr, FullObjectSlot(ring_buffer_ + start_),
FullObjectSlot(ring_buffer_ + std::min(start_ + size_, capacity_)));
Root::kStrongRoots, nullptr, ring_buffer_ + static_cast<int>(start_),
ring_buffer_ + static_cast<int>(std::min(start_ + size_, capacity_)));
visitor->VisitRootPointers(
Root::kStrongRoots, nullptr, FullObjectSlot(ring_buffer_),
FullObjectSlot(ring_buffer_ + std::max(start_ + size_ - capacity_,
static_cast<intptr_t>(0))));
Root::kStrongRoots, nullptr, ring_buffer_,
ring_buffer_ + static_cast<int>(
std::max<intptr_t>(start_ + size_ - capacity_, 0)));
}
if (capacity_ <= kMinimumCapacity) {
......@@ -219,12 +220,14 @@ void MicrotaskQueue::OnCompleted(Isolate* isolate) {
void MicrotaskQueue::ResizeBuffer(intptr_t new_capacity) {
DCHECK_LE(size_, new_capacity);
Address* new_ring_buffer = new Address[new_capacity];
ObjectSlot new_ring_buffer(
reinterpret_cast<Address>(new Microtask[new_capacity]));
for (intptr_t i = 0; i < size_; ++i) {
new_ring_buffer[i] = ring_buffer_[(start_ + i) % capacity_];
(new_ring_buffer + static_cast<int>(i))
.store(*(ring_buffer_ + static_cast<int>((start_ + i) % capacity_)));
}
delete[] ring_buffer_;
delete[] reinterpret_cast<Microtask*>(ring_buffer_.address());
ring_buffer_ = new_ring_buffer;
capacity_ = new_capacity;
start_ = 0;
......
......@@ -12,6 +12,7 @@
#include "include/v8-internal.h" // For Address.
#include "include/v8.h"
#include "src/base/macros.h"
#include "src/objects/slots.h"
namespace v8 {
namespace internal {
......@@ -107,7 +108,7 @@ class V8_EXPORT_PRIVATE MicrotaskQueue {
intptr_t size_ = 0;
intptr_t capacity_ = 0;
intptr_t start_ = 0;
Address* ring_buffer_ = nullptr;
ObjectSlot ring_buffer_;
// The number of finished microtask.
intptr_t finished_microtask_count_ = 0;
......
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