Skip to content

Commit

Permalink
deps: patch V8 to 9.4.146.24
Browse files Browse the repository at this point in the history
  • Loading branch information
targos committed Nov 4, 2021
1 parent af4e682 commit 4c478d9
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 17 deletions.
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

0 comments on commit 4c478d9

Please sign in to comment.