[runtime][api] Fix tracking of entered contexts

The entered contexts stack must be in sync with the flags stack.

Bug: chromium:1269225
Change-Id: Ibb522286b47866d5f13aaec1a0a02914c13a5545
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3279680
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Auto-Submit: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77882}
This commit is contained in:
Igor Sheludko 2021-11-12 21:31:44 +01:00 committed by V8 LUCI CQ
parent d3f1fcaab0
commit 79f617b009
4 changed files with 24 additions and 8 deletions

View File

@ -318,6 +318,7 @@ inline bool V8_EXPORT TryToCopyAndConvertArrayToCppBuffer(Local<Array> src,
namespace internal {
Handle<Context> HandleScopeImplementer::LastEnteredContext() {
DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
for (size_t i = 0; i < entered_contexts_.size(); ++i) {

View File

@ -10451,6 +10451,11 @@ void HandleScopeImplementer::IterateThis(RootVisitor* v) {
v->VisitRootPointers(Root::kHandleScope, nullptr, start,
start + static_cast<int>(context_lists[i]->size()));
}
// The shape of |entered_contexts_| and |is_microtask_context_| stacks must
// be in sync.
is_microtask_context_.shrink_to_fit();
DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
}
void HandleScopeImplementer::Iterate(RootVisitor* v) {

View File

@ -468,6 +468,7 @@ bool HandleScopeImplementer::HasSavedContexts() {
}
void HandleScopeImplementer::EnterContext(Context context) {
DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
entered_contexts_.push_back(context);
is_microtask_context_.push_back(0);
@ -475,6 +476,7 @@ void HandleScopeImplementer::EnterContext(Context context) {
void HandleScopeImplementer::LeaveContext() {
DCHECK(!entered_contexts_.empty());
DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
entered_contexts_.pop_back();
is_microtask_context_.pop_back();
@ -485,6 +487,7 @@ bool HandleScopeImplementer::LastEnteredContextWas(Context context) {
}
void HandleScopeImplementer::EnterMicrotaskContext(Context context) {
DCHECK_EQ(entered_contexts_.capacity(), is_microtask_context_.capacity());
DCHECK_EQ(entered_contexts_.size(), is_microtask_context_.size());
entered_contexts_.push_back(context);
is_microtask_context_.push_back(1);

View File

@ -413,14 +413,23 @@ void MicrotaskQueueBuiltinsAssembler::EnterMicrotaskContext(
TNode<IntPtrT> flag_data_offset =
IntPtrConstant(HandleScopeImplementer::kIsMicrotaskContextOffset +
FlagStack::kDataOffset);
TNode<IntPtrT> flag_capacity_offset =
IntPtrConstant(HandleScopeImplementer::kIsMicrotaskContextOffset +
FlagStack::kCapacityOffset);
TNode<IntPtrT> flag_size_offset =
IntPtrConstant(HandleScopeImplementer::kIsMicrotaskContextOffset +
FlagStack::kSizeOffset);
// Ensure both stacks are in sync.
USE(flag_capacity_offset);
CSA_DCHECK(this,
WordEqual(capacity, Load<IntPtrT>(hsi, flag_capacity_offset)));
CSA_DCHECK(this, WordEqual(size, Load<IntPtrT>(hsi, flag_size_offset)));
TNode<RawPtrT> flag_data = Load<RawPtrT>(hsi, flag_data_offset);
StoreNoWriteBarrier(MachineRepresentation::kWord8, flag_data, size,
BoolConstant(true));
StoreNoWriteBarrier(
MachineType::PointerRepresentation(), hsi,
IntPtrConstant(HandleScopeImplementer::kIsMicrotaskContextOffset +
FlagStack::kSizeOffset),
new_size);
StoreNoWriteBarrier(MachineType::PointerRepresentation(), hsi,
flag_size_offset, new_size);
Goto(&done);
}
@ -449,13 +458,11 @@ void MicrotaskQueueBuiltinsAssembler::RewindEnteredContext(
IntPtrConstant(HandleScopeImplementer::kEnteredContextsOffset +
ContextStack::kSizeOffset);
#ifdef ENABLE_VERIFY_CSA
{
if (DEBUG_BOOL) {
TNode<IntPtrT> size = Load<IntPtrT>(hsi, size_offset);
CSA_CHECK(this, IntPtrLessThan(IntPtrConstant(0), size));
CSA_CHECK(this, IntPtrLessThanOrEqual(saved_entered_context_count, size));
}
#endif
StoreNoWriteBarrier(MachineType::PointerRepresentation(), hsi, size_offset,
saved_entered_context_count);