test-concurrent-marking.cc 5.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdlib.h>

#include "src/v8.h"

#include "src/heap/concurrent-marking.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
12
#include "src/heap/mark-compact.h"
13
#include "src/heap/worklist.h"
14 15 16 17 18
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"

namespace v8 {
namespace internal {
19
namespace heap {
20 21

void PublishSegment(ConcurrentMarking::MarkingWorklist* worklist,
22
                    HeapObject object) {
23
  for (size_t i = 0; i <= ConcurrentMarking::MarkingWorklist::kSegmentCapacity;
24 25 26 27 28 29
       i++) {
    worklist->Push(0, object);
  }
  CHECK(worklist->Pop(0, &object));
}

30
TEST(ConcurrentMarking) {
31
  if (!i::FLAG_concurrent_marking) return;
32 33
  CcTest::InitializeVM();
  Heap* heap = CcTest::heap();
34 35
  CcTest::CollectAllGarbage();
  if (!heap->incremental_marking()->IsStopped()) return;
36 37 38 39
  MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
  if (collector->sweeping_in_progress()) {
    collector->EnsureSweepingCompleted();
  }
40

41
  ConcurrentMarking::MarkingWorklist shared, on_hold;
42
  ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
43
  WeakObjects weak_objects;
44
  ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
45
      heap, &shared, &on_hold, &weak_objects, &embedder_objects);
46
  PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
47
  concurrent_marking->ScheduleTasks();
48 49
  concurrent_marking->Stop(
      ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
50 51 52 53 54 55 56
  delete concurrent_marking;
}

TEST(ConcurrentMarkingReschedule) {
  if (!i::FLAG_concurrent_marking) return;
  CcTest::InitializeVM();
  Heap* heap = CcTest::heap();
57 58
  CcTest::CollectAllGarbage();
  if (!heap->incremental_marking()->IsStopped()) return;
59 60 61 62 63
  MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
  if (collector->sweeping_in_progress()) {
    collector->EnsureSweepingCompleted();
  }

64
  ConcurrentMarking::MarkingWorklist shared, on_hold;
65
  ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
66
  WeakObjects weak_objects;
67
  ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
68
      heap, &shared, &on_hold, &weak_objects, &embedder_objects);
69
  PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
70
  concurrent_marking->ScheduleTasks();
71 72
  concurrent_marking->Stop(
      ConcurrentMarking::StopRequest::COMPLETE_ONGOING_TASKS);
73
  PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
74
  concurrent_marking->RescheduleTasksIfNeeded();
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
  concurrent_marking->Stop(
      ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
  delete concurrent_marking;
}

TEST(ConcurrentMarkingPreemptAndReschedule) {
  if (!i::FLAG_concurrent_marking) return;
  CcTest::InitializeVM();
  Heap* heap = CcTest::heap();
  CcTest::CollectAllGarbage();
  if (!heap->incremental_marking()->IsStopped()) return;
  MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
  if (collector->sweeping_in_progress()) {
    collector->EnsureSweepingCompleted();
  }

91
  ConcurrentMarking::MarkingWorklist shared, on_hold;
92
  ConcurrentMarking::EmbedderTracingWorklist embedder_objects;
93
  WeakObjects weak_objects;
94
  ConcurrentMarking* concurrent_marking = new ConcurrentMarking(
95
      heap, &shared, &on_hold, &weak_objects, &embedder_objects);
96
  for (int i = 0; i < 5000; i++)
97
    PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
98 99 100
  concurrent_marking->ScheduleTasks();
  concurrent_marking->Stop(ConcurrentMarking::StopRequest::PREEMPT_TASKS);
  for (int i = 0; i < 5000; i++)
101
    PublishSegment(&shared, ReadOnlyRoots(heap).undefined_value());
102 103 104
  concurrent_marking->RescheduleTasksIfNeeded();
  concurrent_marking->Stop(
      ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
105 106 107
  delete concurrent_marking;
}

108 109 110 111 112 113 114 115 116 117
TEST(ConcurrentMarkingMarkedBytes) {
  if (!i::FLAG_concurrent_marking) return;
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  Heap* heap = CcTest::heap();
  HandleScope sc(isolate);
  Handle<FixedArray> root = isolate->factory()->NewFixedArray(1000000);
  CcTest::CollectAllGarbage();
  if (!heap->incremental_marking()->IsStopped()) return;
  heap::SimulateIncrementalMarking(heap, false);
118 119
  heap->concurrent_marking()->Stop(
      ConcurrentMarking::StopRequest::COMPLETE_TASKS_FOR_TESTING);
120 121 122
  CHECK_GE(heap->concurrent_marking()->TotalMarkedBytes(), root->Size());
}

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
UNINITIALIZED_TEST(ConcurrentMarkingStoppedOnTeardown) {
  if (!i::FLAG_concurrent_marking) return;

  v8::Isolate::CreateParams create_params;
  create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
  v8::Isolate* isolate = v8::Isolate::New(create_params);

  {
    Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
    Factory* factory = i_isolate->factory();

    v8::Isolate::Scope isolate_scope(isolate);
    v8::HandleScope handle_scope(isolate);
    v8::Context::New(isolate)->Enter();

    for (int i = 0; i < 10000; i++) {
      factory->NewJSWeakMap();
    }

    Heap* heap = i_isolate->heap();
    heap::SimulateIncrementalMarking(heap, false);
  }

  isolate->Dispose();
}

149
}  // namespace heap
150 151
}  // namespace internal
}  // namespace v8