Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v16.x] deps: patch V8 to 9.4.146.24 #40616

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions deps/v8/OWNERS
Expand Up @@ -27,6 +27,10 @@ per-file codereview.settings=file:INFRA_OWNERS
per-file AUTHORS=file:COMMON_OWNERS
per-file WATCHLISTS=file:COMMON_OWNERS

# Needed by the auto_tag builder
per-file WATCHLISTS=v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com
per-file DEPS=v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com

per-file ...-mips*=file:MIPS_OWNERS
per-file ...-mips64*=file:MIPS_OWNERS
per-file ...-ppc*=file:PPC_OWNERS
Expand Down
3 changes: 3 additions & 0 deletions deps/v8/include/OWNERS
Expand Up @@ -11,6 +11,9 @@ per-file v8-inspector.h=file:../src/inspector/OWNERS
per-file v8-inspector-protocol.h=file:../src/inspector/OWNERS
per-file js_protocol.pdl=file:../src/inspector/OWNERS

# Needed by the auto_tag builder
per-file v8-version.h=v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com

# For branch updates:
per-file v8-version.h=file:../INFRA_OWNERS
per-file v8-version.h=hablich@chromium.org
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/include/v8-version.h
Expand Up @@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 9
#define V8_MINOR_VERSION 4
#define V8_BUILD_NUMBER 146
#define V8_PATCH_LEVEL 19
#define V8_PATCH_LEVEL 24

// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/execution/isolate-inl.h
Expand Up @@ -50,7 +50,7 @@ bool Isolate::has_pending_message() {
}

Object Isolate::pending_exception() {
DCHECK(has_pending_exception());
CHECK(has_pending_exception());
DCHECK(!thread_local_top()->pending_exception_.IsException(this));
return thread_local_top()->pending_exception_;
}
Expand Down
8 changes: 7 additions & 1 deletion deps/v8/src/heap/cppgc/marker.cc
Expand Up @@ -243,6 +243,7 @@ void MarkerBase::EnterAtomicPause(MarkingConfig::StackState stack_state) {
}
config_.stack_state = stack_state;
config_.marking_type = MarkingConfig::MarkingType::kAtomic;
mutator_marking_state_.set_in_atomic_pause();

// Lock guards against changes to {Weak}CrossThreadPersistent handles, that
// may conflict with marking. E.g., a WeakCrossThreadPersistent may be
Expand Down Expand Up @@ -421,7 +422,9 @@ bool MarkerBase::ProcessWorklistsWithDeadline(
size_t marked_bytes_deadline, v8::base::TimeTicks time_deadline) {
StatsCollector::EnabledScope stats_scope(
heap().stats_collector(), StatsCollector::kMarkTransitiveClosure);
bool saved_did_discover_new_ephemeron_pairs;
do {
mutator_marking_state_.ResetDidDiscoverNewEphemeronPairs();
if ((config_.marking_type == MarkingConfig::MarkingType::kAtomic) ||
schedule_.ShouldFlushEphemeronPairs()) {
mutator_marking_state_.FlushDiscoveredEphemeronPairs();
Expand Down Expand Up @@ -509,6 +512,8 @@ bool MarkerBase::ProcessWorklistsWithDeadline(
}
}

saved_did_discover_new_ephemeron_pairs =
mutator_marking_state_.DidDiscoverNewEphemeronPairs();
{
StatsCollector::EnabledScope stats_scope(
heap().stats_collector(), StatsCollector::kMarkProcessEphemerons);
Expand All @@ -522,7 +527,8 @@ bool MarkerBase::ProcessWorklistsWithDeadline(
return false;
}
}
} while (!mutator_marking_state_.marking_worklist().IsLocalAndGlobalEmpty());
} while (!mutator_marking_state_.marking_worklist().IsLocalAndGlobalEmpty() ||
saved_did_discover_new_ephemeron_pairs);
return true;
}

Expand Down
41 changes: 35 additions & 6 deletions deps/v8/src/heap/cppgc/marking-state.h
Expand Up @@ -9,6 +9,7 @@

#include "include/cppgc/trace-trait.h"
#include "include/cppgc/visitor.h"
#include "src/base/logging.h"
#include "src/heap/cppgc/compaction-worklists.h"
#include "src/heap/cppgc/globals.h"
#include "src/heap/cppgc/heap-object-header.h"
Expand Down Expand Up @@ -115,6 +116,16 @@ class MarkingStateBase {
movable_slots_worklist_.reset();
}

bool DidDiscoverNewEphemeronPairs() const {
return discovered_new_ephemeron_pairs_;
}

void ResetDidDiscoverNewEphemeronPairs() {
discovered_new_ephemeron_pairs_ = false;
}

void set_in_atomic_pause() { in_atomic_pause_ = true; }

protected:
inline void MarkAndPush(HeapObjectHeader&, TraceDescriptor);

Expand Down Expand Up @@ -150,6 +161,9 @@ class MarkingStateBase {
movable_slots_worklist_;

size_t marked_bytes_ = 0;
bool in_ephemeron_processing_ = false;
bool discovered_new_ephemeron_pairs_ = false;
bool in_atomic_pause_ = false;
};

MarkingStateBase::MarkingStateBase(HeapBase& heap,
Expand Down Expand Up @@ -286,20 +300,35 @@ void MarkingStateBase::ProcessWeakContainer(const void* object,
void MarkingStateBase::ProcessEphemeron(const void* key, const void* value,
TraceDescriptor value_desc,
Visitor& visitor) {
// Filter out already marked keys. The write barrier for WeakMember
// ensures that any newly set value after this point is kept alive and does
// not require the callback.
if (HeapObjectHeader::FromObject(key).IsMarked<AccessMode::kAtomic>()) {
// ProcessEphemeron is not expected to find new ephemerons recursively, which
// would break the main marking loop.
DCHECK(!in_ephemeron_processing_);
in_ephemeron_processing_ = true;
// Keys are considered live even in incremental/concurrent marking settings
// because the write barrier for WeakMember ensures that any newly set value
// after this point is kept alive and does not require the callback.
const bool key_in_construction =
HeapObjectHeader::FromObject(key).IsInConstruction<AccessMode::kAtomic>();
const bool key_considered_as_live =
key_in_construction
? in_atomic_pause_
: HeapObjectHeader::FromObject(key).IsMarked<AccessMode::kAtomic>();
DCHECK_IMPLIES(
key_in_construction && in_atomic_pause_,
HeapObjectHeader::FromObject(key).IsMarked<AccessMode::kAtomic>());
if (key_considered_as_live) {
if (value_desc.base_object_payload) {
MarkAndPush(value_desc.base_object_payload, value_desc);
} else {
// If value_desc.base_object_payload is nullptr, the value is not GCed and
// should be immediately traced.
value_desc.callback(&visitor, value);
}
return;
} else {
discovered_ephemeron_pairs_worklist_.Push({key, value, value_desc});
discovered_new_ephemeron_pairs_ = true;
}
discovered_ephemeron_pairs_worklist_.Push({key, value, value_desc});
in_ephemeron_processing_ = false;
}

void MarkingStateBase::AccountMarkedBytes(const HeapObjectHeader& header) {
Expand Down
4 changes: 2 additions & 2 deletions deps/v8/src/ic/accessor-assembler.cc
Expand Up @@ -846,8 +846,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
Comment("module export");
TNode<UintPtrT> index =
DecodeWord<LoadHandler::ExportsIndexBits>(handler_word);
TNode<Module> module = LoadObjectField<Module>(
CAST(p->receiver()), JSModuleNamespace::kModuleOffset);
TNode<Module> module =
LoadObjectField<Module>(CAST(holder), JSModuleNamespace::kModuleOffset);
TNode<ObjectHashTable> exports =
LoadObjectField<ObjectHashTable>(module, Module::kExportsOffset);
TNode<Cell> cell = CAST(LoadFixedArrayElement(exports, index));
Expand Down
8 changes: 7 additions & 1 deletion deps/v8/src/ic/ic.cc
Expand Up @@ -989,7 +989,13 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
// We found the accessor, so the entry must exist.
DCHECK(entry.is_found());
int index = ObjectHashTable::EntryToValueIndex(entry);
return LoadHandler::LoadModuleExport(isolate(), index);
Handle<Smi> smi_handler =
LoadHandler::LoadModuleExport(isolate(), index);
if (holder_is_lookup_start_object) {
return smi_handler;
}
return LoadHandler::LoadFromPrototype(isolate(), map, holder,
smi_handler);
}

Handle<Object> accessors = lookup->GetAccessors();
Expand Down
8 changes: 4 additions & 4 deletions deps/v8/src/wasm/module-compiler.cc
Expand Up @@ -3052,13 +3052,13 @@ void CompilationStateImpl::InitializeCompilationProgressAfterDeserialization(
}
compilation_progress_.assign(module->num_declared_functions,
kProgressAfterDeserialization);
uint32_t num_imported_functions = module->num_imported_functions;
for (auto func_index : missing_functions) {
if (FLAG_wasm_lazy_compilation) {
native_module_->UseLazyStub(num_imported_functions + func_index);
native_module_->UseLazyStub(func_index);
}
compilation_progress_[func_index] = SetupCompilationProgressForFunction(
lazy_module, module, enabled_features, func_index);
compilation_progress_[declared_function_index(module, func_index)] =
SetupCompilationProgressForFunction(lazy_module, module,
enabled_features, func_index);
}
}
auto builder = std::make_unique<CompilationUnitBuilder>(native_module_);
Expand Down
Expand Up @@ -10,6 +10,7 @@ const num_functions = 2;

function create_builder() {
const builder = new WasmModuleBuilder();
builder.addImport("foo", "bar", kSig_i_v);
for (let i = 0; i < num_functions; ++i) {
builder.addFunction('f' + i, kSig_i_v)
.addBody(wasmI32Const(i))
Expand Down Expand Up @@ -37,7 +38,7 @@ gc();
print(arguments.callee.name);
const module = %DeserializeWasmModule(serialized_module, wire_bytes);

const instance = new WebAssembly.Instance(module);
const instance = new WebAssembly.Instance(module, {foo: {bar: () => 1}});
assertEquals(0, instance.exports.f0());
assertEquals(1, instance.exports.f1());
})();
45 changes: 45 additions & 0 deletions deps/v8/test/unittests/heap/cppgc/ephemeron-pair-unittest.cc
Expand Up @@ -242,5 +242,50 @@ TEST_F(EphemeronPairTest, EphemeronPairWithEmptyMixinValue) {
FinishMarking();
}

namespace {

class KeyWithCallback final : public GarbageCollected<KeyWithCallback> {
public:
template <typename Callback>
explicit KeyWithCallback(Callback callback) {
callback(this);
}
void Trace(Visitor*) const {}
};

class EphemeronHolderForKeyWithCallback final
: public GarbageCollected<EphemeronHolderForKeyWithCallback> {
public:
EphemeronHolderForKeyWithCallback(KeyWithCallback* key, GCed* value)
: ephemeron_pair_(key, value) {}
void Trace(cppgc::Visitor* visitor) const { visitor->Trace(ephemeron_pair_); }

private:
const EphemeronPair<KeyWithCallback, GCed> ephemeron_pair_;
};

} // namespace

TEST_F(EphemeronPairTest, EphemeronPairWithKeyInConstruction) {
GCed* value = MakeGarbageCollected<GCed>(GetAllocationHandle());
Persistent<EphemeronHolderForKeyWithCallback> holder;
InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get());
FinishSteps();
MakeGarbageCollected<KeyWithCallback>(
GetAllocationHandle(), [this, &holder, value](KeyWithCallback* thiz) {
// The test doesn't use conservative stack scanning to retain key to
// avoid retaining value as a side effect.
EXPECT_TRUE(HeapObjectHeader::FromObject(thiz).TryMarkAtomic());
holder = MakeGarbageCollected<EphemeronHolderForKeyWithCallback>(
GetAllocationHandle(), thiz, value);
// Finishing marking at this point will leave an ephemeron pair
// reachable where the key is still in construction. The GC needs to
// mark the value for such pairs as live in the atomic pause as they key
// is considered live.
FinishMarking();
});
EXPECT_TRUE(HeapObjectHeader::FromObject(value).IsMarked());
}

} // namespace internal
} // namespace cppgc
48 changes: 48 additions & 0 deletions deps/v8/test/unittests/heap/cppgc/marker-unittest.cc
Expand Up @@ -7,12 +7,14 @@
#include <memory>

#include "include/cppgc/allocation.h"
#include "include/cppgc/ephemeron-pair.h"
#include "include/cppgc/internal/pointer-policies.h"
#include "include/cppgc/member.h"
#include "include/cppgc/persistent.h"
#include "include/cppgc/trace-trait.h"
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/marking-visitor.h"
#include "src/heap/cppgc/object-allocator.h"
#include "src/heap/cppgc/stats-collector.h"
#include "test/unittests/heap/cppgc/tests.h"
#include "testing/gtest/include/gtest/gtest.h"
Expand Down Expand Up @@ -44,6 +46,8 @@ class MarkerTest : public testing::TestWithHeap {

Marker* marker() const { return marker_.get(); }

void ResetMarker() { marker_.reset(); }

private:
std::unique_ptr<Marker> marker_;
};
Expand Down Expand Up @@ -346,6 +350,50 @@ TEST_F(MarkerTest, SentinelNotClearedOnWeakPersistentHandling) {
EXPECT_EQ(kSentinelPointer, root->weak_child());
}

namespace {

class SimpleObject final : public GarbageCollected<SimpleObject> {
public:
void Trace(Visitor*) const {}
};

class ObjectWithEphemeronPair final
: public GarbageCollected<ObjectWithEphemeronPair> {
public:
explicit ObjectWithEphemeronPair(AllocationHandle& handle)
: ephemeron_pair_(MakeGarbageCollected<SimpleObject>(handle),
MakeGarbageCollected<SimpleObject>(handle)) {}

void Trace(Visitor* visitor) const {
// First trace the ephemeron pair. The key is not yet marked as live, so the
// pair should be recorded for later processing. Then strongly mark the key.
// Marking the key will not trigger another worklist processing iteration,
// as it merely continues the same loop for regular objects and will leave
// the main marking worklist empty. If recording the ephemeron pair doesn't
// as well, we will get a crash when destroying the marker.
visitor->Trace(ephemeron_pair_);
visitor->Trace(const_cast<const SimpleObject*>(ephemeron_pair_.key.Get()));
}

private:
const EphemeronPair<SimpleObject, SimpleObject> ephemeron_pair_;
};

} // namespace

TEST_F(MarkerTest, MarkerProcessesAllEphemeronPairs) {
static const Marker::MarkingConfig config = {
MarkingConfig::CollectionType::kMajor,
MarkingConfig::StackState::kNoHeapPointers,
MarkingConfig::MarkingType::kAtomic};
Persistent<ObjectWithEphemeronPair> obj =
MakeGarbageCollected<ObjectWithEphemeronPair>(GetAllocationHandle(),
GetAllocationHandle());
InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get(), config);
marker()->FinishMarking(MarkingConfig::StackState::kNoHeapPointers);
ResetMarker();
}

// Incremental Marking

class IncrementalMarkingTest : public testing::TestWithHeap {
Expand Down