Bug 1689601, sync fields when loading a page from bfcache, r=peterv

Differential Revision: https://phabricator.services.mozilla.com/D106737
This commit is contained in:
Olli Pettay
2021-03-02 12:13:22 +00:00
parent da49f813a4
commit bac6e28ee3
3 changed files with 40 additions and 4 deletions

View File

@@ -168,14 +168,24 @@ void CanonicalBrowsingContext::ReplacedBy(
mStatusFilter = nullptr; mStatusFilter = nullptr;
} }
aNewContext->mWebProgress = std::move(mWebProgress); aNewContext->mWebProgress = std::move(mWebProgress);
aNewContext->mFields.SetWithoutSyncing<IDX_BrowserId>(GetBrowserId());
aNewContext->mFields.SetWithoutSyncing<IDX_HistoryID>(GetHistoryID()); // Use the Transaction for the fields which need to be updated whether or not
aNewContext->mFields.SetWithoutSyncing<IDX_ExplicitActive>( // the new context has been attached before.
GetExplicitActive()); // SetWithoutSyncing can be used if context hasn't been attached.
Transaction txn;
txn.SetBrowserId(GetBrowserId());
txn.SetHistoryID(GetHistoryID());
txn.SetExplicitActive(GetExplicitActive());
if (aNewContext->EverAttached()) {
MOZ_ALWAYS_SUCCEEDS(txn.Commit(aNewContext));
} else {
txn.CommitWithoutSyncing(aNewContext);
}
// XXXBFCache name handling is still a bit broken in Fission in general, // XXXBFCache name handling is still a bit broken in Fission in general,
// at least in case name should be cleared. // at least in case name should be cleared.
if (aRemotenessOptions.mTryUseBFCache) { if (aRemotenessOptions.mTryUseBFCache) {
MOZ_ASSERT(!aNewContext->EverAttached());
aNewContext->mFields.SetWithoutSyncing<IDX_Name>(GetName()); aNewContext->mFields.SetWithoutSyncing<IDX_Name>(GetName());
aNewContext->mFields.SetWithoutSyncing<IDX_HasLoadedNonInitialDocument>( aNewContext->mFields.SetWithoutSyncing<IDX_HasLoadedNonInitialDocument>(
GetHasLoadedNonInitialDocument()); GetHasLoadedNonInitialDocument());

View File

@@ -74,6 +74,16 @@ class Transaction {
mozilla::ipc::IPCResult CommitFromIPC(const MaybeDiscarded<Context>& aOwner, mozilla::ipc::IPCResult CommitFromIPC(const MaybeDiscarded<Context>& aOwner,
uint64_t aEpoch, ContentChild* aSource); uint64_t aEpoch, ContentChild* aSource);
// Apply the changes from this transaction to the specified Context WITHOUT
// syncing the changes to other processes.
//
// Unlike `Commit`, this method will NOT call the corresponding `CanSet` or
// `DidSet` methods, and can be performed when the target context is
// unattached or discarded.
//
// NOTE: YOU PROBABLY DO NOT WANT TO USE THIS METHOD
void CommitWithoutSyncing(Context* aOwner);
private: private:
friend struct mozilla::ipc::IPDLParamTraits<Transaction<Context>>; friend struct mozilla::ipc::IPDLParamTraits<Transaction<Context>>;

View File

@@ -223,6 +223,22 @@ void Transaction<Context>::Apply(Context* aOwner, bool aFromIPC) {
mModified.clear(); mModified.clear();
} }
template <typename Context>
void Transaction<Context>::CommitWithoutSyncing(Context* aOwner) {
MOZ_LOG(
Context::GetSyncLog(), LogLevel::Debug,
("Transaction::CommitWithoutSyncing(#%" PRIx64 "): %s", aOwner->Id(),
FormatTransaction<Context>(mModified, aOwner->mFields.mValues, mValues)
.get()));
EachIndex([&](auto idx) {
if (mModified.contains(idx)) {
aOwner->mFields.mValues.Get(idx) = std::move(mValues.Get(idx));
}
});
mModified.clear();
}
inline CanSetResult AsCanSetResult(CanSetResult aValue) { return aValue; } inline CanSetResult AsCanSetResult(CanSetResult aValue) { return aValue; }
inline CanSetResult AsCanSetResult(bool aValue) { inline CanSetResult AsCanSetResult(bool aValue) {
return aValue ? CanSetResult::Allow : CanSetResult::Deny; return aValue ? CanSetResult::Allow : CanSetResult::Deny;