summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync/syncable/syncable.cc21
1 files changed, 18 insertions, 3 deletions
diff --git a/chrome/browser/sync/syncable/syncable.cc b/chrome/browser/sync/syncable/syncable.cc
index 4ece5bd..288c3dd 100644
--- a/chrome/browser/sync/syncable/syncable.cc
+++ b/chrome/browser/sync/syncable/syncable.cc
@@ -64,6 +64,9 @@ static const InvariantCheckLevel kInvariantCheckLevel = VERIFY_IN_MEMORY;
// Max number of milliseconds to spend checking syncable entry invariants
static const int kInvariantCheckMaxMs = 50;
+
+// Max number of mutations in a mutation set we permit passing to observers.
+static const size_t kMutationObserverLimit = 1000;
} // namespace
using std::string;
@@ -1257,9 +1260,21 @@ ModelTypeBitSet WriteTransaction::NotifyTransactionChangingAndEnding(
ModelTypeBitSet models_with_changes =
delegate->HandleTransactionEndingChangeEvent(this);
- dirkernel_->observers->Notify(
- &TransactionObserver::OnTransactionMutate,
- from_here_, writer_, mutations, models_with_changes);
+ // These notifications pass the mutation list around by value, which when we
+ // rewrite all sync data can be extremely large and result in out of memory
+ // errors (see crbug.com/90169). As a result, when there are more than
+ // kMutationObserverLimit mutations, we pass around an empty mutation set.
+ if (mutations.size() < kMutationObserverLimit) {
+ dirkernel_->observers->Notify(
+ &TransactionObserver::OnTransactionMutate,
+ from_here_, writer_, mutations, models_with_changes);
+ } else {
+ EntryKernelMutationSet dummy_mutations; // Empty set.
+ dirkernel_->observers->Notify(
+ &TransactionObserver::OnTransactionMutate,
+ from_here_, writer_, dummy_mutations, models_with_changes);
+ }
+
return models_with_changes;
}