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