| Index: src/heap/incremental-marking.cc
 | 
| diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc
 | 
| index b9e7c61ba05942c8f9c2ce81a29569d3e2935527..3c3cf9a03d95057d7e552c9e939ccc18f738a17e 100644
 | 
| --- a/src/heap/incremental-marking.cc
 | 
| +++ b/src/heap/incremental-marking.cc
 | 
| @@ -742,7 +742,6 @@ void IncrementalMarking::RetainMaps() {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -
 | 
|  void IncrementalMarking::FinalizeIncrementally() {
 | 
|    TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_INCREMENTAL_FINALIZE_BODY);
 | 
|    DCHECK(!finalize_marking_completed_);
 | 
| @@ -775,6 +774,9 @@ void IncrementalMarking::FinalizeIncrementally() {
 | 
|        abs(old_marking_deque_top -
 | 
|            heap_->mark_compact_collector()->marking_deque()->top());
 | 
|  
 | 
| +  marking_progress +=
 | 
| +      static_cast<int>(heap_->mark_compact_collector()->wrappers_to_trace());
 | 
| +
 | 
|    double end = heap_->MonotonicallyIncreasingTimeInMs();
 | 
|    double delta = end - start;
 | 
|    heap_->tracer()->AddMarkingTime(delta);
 | 
| @@ -1048,7 +1050,7 @@ double IncrementalMarking::AdvanceIncrementalMarking(
 | 
|               step_actions.force_marking, step_actions.force_completion);
 | 
|      remaining_time_in_ms =
 | 
|          deadline_in_ms - heap()->MonotonicallyIncreasingTimeInMs();
 | 
| -  } while (bytes_processed > 0 &&
 | 
| +  } while (!heap_->mark_compact_collector()->marking_deque()->IsEmpty() &&
 | 
|             remaining_time_in_ms >=
 | 
|                 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs &&
 | 
|             !IsComplete() &&
 | 
| @@ -1206,23 +1208,35 @@ intptr_t IncrementalMarking::Step(intptr_t allocated_bytes,
 | 
|      }
 | 
|  
 | 
|      if (state_ == MARKING) {
 | 
| -      bytes_processed = ProcessMarkingDeque(bytes_to_process);
 | 
| -      if (FLAG_incremental_marking_wrappers &&
 | 
| -          heap_->UsingEmbedderHeapTracer()) {
 | 
| +      const bool incremental_wrapper_tracing =
 | 
| +          FLAG_incremental_marking_wrappers && heap_->UsingEmbedderHeapTracer();
 | 
| +      const bool process_wrappers =
 | 
| +          incremental_wrapper_tracing &&
 | 
| +          (heap_->mark_compact_collector()
 | 
| +               ->RequiresImmediateWrapperProcessing() ||
 | 
| +           heap_->mark_compact_collector()->marking_deque()->IsEmpty());
 | 
| +      bool wrapper_work_left = incremental_wrapper_tracing;
 | 
| +      if (!process_wrappers) {
 | 
| +        bytes_processed = ProcessMarkingDeque(bytes_to_process);
 | 
| +      } else {
 | 
| +        const double kWrapperTracngStepMs = 1.0;
 | 
| +        const double wrapper_deadline =
 | 
| +            heap_->MonotonicallyIncreasingTimeInMs() + kWrapperTracngStepMs;
 | 
|          TRACE_GC(heap()->tracer(),
 | 
|                   GCTracer::Scope::MC_INCREMENTAL_WRAPPER_TRACING);
 | 
| -        // This currently marks through all registered wrappers and does not
 | 
| -        // respect bytes_to_process.
 | 
| -        // TODO(hpayer): Integrate incremental marking of wrappers into
 | 
| -        // bytes_to_process logic.
 | 
|          heap_->mark_compact_collector()
 | 
|              ->RegisterWrappersWithEmbedderHeapTracer();
 | 
| -        heap_->mark_compact_collector()->embedder_heap_tracer()->AdvanceTracing(
 | 
| -            0,
 | 
| -            EmbedderHeapTracer::AdvanceTracingActions(
 | 
| -                EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION));
 | 
| +        wrapper_work_left =
 | 
| +            heap_->mark_compact_collector()
 | 
| +                ->embedder_heap_tracer()
 | 
| +                ->AdvanceTracing(wrapper_deadline,
 | 
| +                                 EmbedderHeapTracer::AdvanceTracingActions(
 | 
| +                                     EmbedderHeapTracer::ForceCompletionAction::
 | 
| +                                         DO_NOT_FORCE_COMPLETION));
 | 
|        }
 | 
| -      if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) {
 | 
| +
 | 
| +      if (heap_->mark_compact_collector()->marking_deque()->IsEmpty() &&
 | 
| +          !wrapper_work_left) {
 | 
|          if (completion == FORCE_COMPLETION ||
 | 
|              IsIdleMarkingDelayCounterLimitReached()) {
 | 
|            if (!finalize_marking_completed_) {
 | 
| 
 |