test-concurrent-marking.cc 5.07 KB
Newer Older
1 2 3 4 5 6 7 8 9
// 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/heap/concurrent-marking.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
10
#include "src/heap/mark-compact.h"
11 12
#include "src/heap/marking-worklist-inl.h"
#include "src/heap/marking-worklist.h"
13
#include "src/heap/worklist.h"
14
#include "src/init/v8.h"
15 16 17 18 19
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"

namespace v8 {
namespace internal {
20
namespace heap {
21

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

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
  MarkingWorklists marking_worklists;
42
  WeakObjects weak_objects;
43
  ConcurrentMarking* concurrent_marking =
44 45
      new ConcurrentMarking(heap, &marking_worklists, &weak_objects);
  PublishSegment(marking_worklists.shared(),
46
                 ReadOnlyRoots(heap).undefined_value());
47 48
  concurrent_marking->ScheduleJob();
  concurrent_marking->Join();
49 50 51 52 53 54 55
  delete concurrent_marking;
}

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

63
  MarkingWorklists marking_worklists;
64
  WeakObjects weak_objects;
65
  ConcurrentMarking* concurrent_marking =
66 67
      new ConcurrentMarking(heap, &marking_worklists, &weak_objects);
  PublishSegment(marking_worklists.shared(),
68
                 ReadOnlyRoots(heap).undefined_value());
69 70
  concurrent_marking->ScheduleJob();
  concurrent_marking->Join();
71
  PublishSegment(marking_worklists.shared(),
72
                 ReadOnlyRoots(heap).undefined_value());
73 74
  concurrent_marking->RescheduleJobIfNeeded();
  concurrent_marking->Join();
75 76 77 78 79 80 81 82 83 84 85 86 87 88
  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();
  }

89
  MarkingWorklists marking_worklists;
90
  WeakObjects weak_objects;
91
  ConcurrentMarking* concurrent_marking =
92
      new ConcurrentMarking(heap, &marking_worklists, &weak_objects);
93
  for (int i = 0; i < 5000; i++)
94
    PublishSegment(marking_worklists.shared(),
95
                   ReadOnlyRoots(heap).undefined_value());
96 97
  concurrent_marking->ScheduleJob();
  concurrent_marking->Pause();
98
  for (int i = 0; i < 5000; i++)
99
    PublishSegment(marking_worklists.shared(),
100
                   ReadOnlyRoots(heap).undefined_value());
101 102
  concurrent_marking->RescheduleJobIfNeeded();
  concurrent_marking->Join();
103 104 105
  delete concurrent_marking;
}

106
TEST(ConcurrentMarkingMarkedBytes) {
107
  if (!FLAG_incremental_marking) return;
108 109 110 111 112 113 114 115
  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;
116 117 118 119 120 121

  // Store array in Global such that it is part of the root set when
  // starting incremental marking.
  v8::Global<Value> global_root(CcTest::isolate(),
                                Utils::ToLocal(Handle<Object>::cast(root)));

122
  heap::SimulateIncrementalMarking(heap, false);
123
  heap->concurrent_marking()->Join();
124 125 126
  CHECK_GE(heap->concurrent_marking()->TotalMarkedBytes(), root->Size());
}

127
UNINITIALIZED_TEST(ConcurrentMarkingStoppedOnTeardown) {
128
  if (!FLAG_incremental_marking) return;
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  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();
}

154
}  // namespace heap
155 156
}  // namespace internal
}  // namespace v8