11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/heap/scavenge-job.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/base/platform/time.h"
81cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
91cb0ef41Sopenharmony_ci#include "src/execution/vm-state-inl.h"
101cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
111cb0ef41Sopenharmony_ci#include "src/heap/heap.h"
121cb0ef41Sopenharmony_ci#include "src/init/v8.h"
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace v8 {
151cb0ef41Sopenharmony_cinamespace internal {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciclass ScavengeJob::Task : public CancelableTask {
181cb0ef41Sopenharmony_ci public:
191cb0ef41Sopenharmony_ci  Task(Isolate* isolate, ScavengeJob* job)
201cb0ef41Sopenharmony_ci      : CancelableTask(isolate), isolate_(isolate), job_(job) {}
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci  // CancelableTask overrides.
231cb0ef41Sopenharmony_ci  void RunInternal() override;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci  Isolate* isolate() const { return isolate_; }
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci private:
281cb0ef41Sopenharmony_ci  Isolate* const isolate_;
291cb0ef41Sopenharmony_ci  ScavengeJob* const job_;
301cb0ef41Sopenharmony_ci};
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cisize_t ScavengeJob::YoungGenerationTaskTriggerSize(Heap* heap) {
331cb0ef41Sopenharmony_ci  return heap->new_space()->Capacity() * FLAG_scavenge_task_trigger / 100;
341cb0ef41Sopenharmony_ci}
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cibool ScavengeJob::YoungGenerationSizeTaskTriggerReached(Heap* heap) {
371cb0ef41Sopenharmony_ci  return heap->new_space()->Size() >= YoungGenerationTaskTriggerSize(heap);
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_civoid ScavengeJob::ScheduleTaskIfNeeded(Heap* heap) {
411cb0ef41Sopenharmony_ci  if (FLAG_scavenge_task && !task_pending_ && !heap->IsTearingDown() &&
421cb0ef41Sopenharmony_ci      YoungGenerationSizeTaskTriggerReached(heap)) {
431cb0ef41Sopenharmony_ci    v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate());
441cb0ef41Sopenharmony_ci    auto taskrunner =
451cb0ef41Sopenharmony_ci        V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate);
461cb0ef41Sopenharmony_ci    if (taskrunner->NonNestableTasksEnabled()) {
471cb0ef41Sopenharmony_ci      taskrunner->PostNonNestableTask(
481cb0ef41Sopenharmony_ci          std::make_unique<Task>(heap->isolate(), this));
491cb0ef41Sopenharmony_ci      task_pending_ = true;
501cb0ef41Sopenharmony_ci    }
511cb0ef41Sopenharmony_ci  }
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_civoid ScavengeJob::Task::RunInternal() {
551cb0ef41Sopenharmony_ci  VMState<GC> state(isolate());
561cb0ef41Sopenharmony_ci  TRACE_EVENT_CALL_STATS_SCOPED(isolate(), "v8", "V8.Task");
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  if (ScavengeJob::YoungGenerationSizeTaskTriggerReached(isolate()->heap())) {
591cb0ef41Sopenharmony_ci    isolate()->heap()->CollectGarbage(NEW_SPACE,
601cb0ef41Sopenharmony_ci                                      GarbageCollectionReason::kTask);
611cb0ef41Sopenharmony_ci  }
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  job_->set_task_pending(false);
641cb0ef41Sopenharmony_ci}
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci}  // namespace internal
671cb0ef41Sopenharmony_ci}  // namespace v8
68