void SetObjectGroupId(internal::Object** object, UniqueId id);
void SetReferenceFromGroup(UniqueId id, internal::Object** object);
void SetReference(internal::Object** parent, internal::Object** child);
- void CollectAllGarbage(const char* gc_reason);
+ void ReportExternalAllocationLimitReached();
};
class V8_EXPORT StartupData {
if (change_in_bytes > 0 &&
amount - *amount_of_external_allocated_memory_at_last_global_gc >
I::kExternalAllocationLimit) {
- CollectAllGarbage("external memory allocation limit reached.");
+ ReportExternalAllocationLimitReached();
}
*amount_of_external_allocated_memory = amount;
return *amount_of_external_allocated_memory;
}
-void Isolate::CollectAllGarbage(const char* gc_reason) {
+void Isolate::ReportExternalAllocationLimitReached() {
i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
DCHECK_EQ(heap->gc_state(), i::Heap::NOT_IN_GC);
- if (heap->incremental_marking()->IsStopped()) {
- if (heap->incremental_marking()->CanBeActivated()) {
- heap->StartIncrementalMarking(
- i::Heap::kNoGCFlags,
- kGCCallbackFlagSynchronousPhantomCallbackProcessing, gc_reason);
- } else {
- heap->CollectAllGarbage(
- i::Heap::kNoGCFlags, gc_reason,
- kGCCallbackFlagSynchronousPhantomCallbackProcessing);
- }
- } else {
- // Incremental marking is turned on an has already been started.
-
- // TODO(mlippautz): Compute the time slice for incremental marking based on
- // memory pressure.
- double deadline = heap->MonotonicallyIncreasingTimeInMs() +
- i::FLAG_external_allocation_limit_incremental_time;
- heap->AdvanceIncrementalMarking(
- 0, deadline, i::IncrementalMarking::StepActions(
- i::IncrementalMarking::GC_VIA_STACK_GUARD,
- i::IncrementalMarking::FORCE_MARKING,
- i::IncrementalMarking::FORCE_COMPLETION));
- }
+ heap->ReportExternalMemoryPressure(
+ "external memory allocation limit reached.");
}
scavenge_collector_(nullptr),
mark_compact_collector_(nullptr),
store_buffer_(this),
- incremental_marking_(this),
+ incremental_marking_(nullptr),
gc_idle_time_handler_(nullptr),
memory_reducer_(nullptr),
object_stats_(nullptr),
}
+void Heap::ReportExternalMemoryPressure(const char* gc_reason) {
+ if (incremental_marking()->IsStopped()) {
+ if (incremental_marking()->CanBeActivated()) {
+ StartIncrementalMarking(
+ i::Heap::kNoGCFlags,
+ kGCCallbackFlagSynchronousPhantomCallbackProcessing, gc_reason);
+ } else {
+ CollectAllGarbage(i::Heap::kNoGCFlags, gc_reason,
+ kGCCallbackFlagSynchronousPhantomCallbackProcessing);
+ }
+ } else {
+ // Incremental marking is turned on an has already been started.
+
+ // TODO(mlippautz): Compute the time slice for incremental marking based on
+ // memory pressure.
+ double deadline = MonotonicallyIncreasingTimeInMs() +
+ FLAG_external_allocation_limit_incremental_time;
+ incremental_marking()->AdvanceIncrementalMarking(
+ 0, deadline,
+ IncrementalMarking::StepActions(IncrementalMarking::GC_VIA_STACK_GUARD,
+ IncrementalMarking::FORCE_MARKING,
+ IncrementalMarking::FORCE_COMPLETION));
+ }
+}
+
+
void Heap::EnsureFillerObjectAtTop() {
// There may be an allocation memento behind every object in new space.
// If we evacuate a not full new space or if we are on the last page of
}
-double Heap::AdvanceIncrementalMarking(
- intptr_t step_size_in_bytes, double deadline_in_ms,
- IncrementalMarking::StepActions step_actions) {
- DCHECK(!incremental_marking()->IsStopped());
-
- if (step_size_in_bytes == 0) {
- step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize(
- static_cast<size_t>(GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs),
- static_cast<size_t>(
- tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()));
- }
-
- double remaining_time_in_ms = 0.0;
- do {
- incremental_marking()->Step(
- step_size_in_bytes, step_actions.completion_action,
- step_actions.force_marking, step_actions.force_completion);
- remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
- } while (remaining_time_in_ms >=
- 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs &&
- !incremental_marking()->IsComplete() &&
- !mark_compact_collector()->marking_deque()->IsEmpty());
- return remaining_time_in_ms;
-}
-
-
bool Heap::PerformIdleTimeAction(GCIdleTimeAction action,
GCIdleTimeHeapState heap_state,
double deadline_in_ms) {
if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize()))
return false;
+ // Initialize incremental marking.
+ incremental_marking_ = new IncrementalMarking(this);
+
// Set up new space.
if (!new_space_.SetUp(reserved_semispace_size_, max_semi_space_size_)) {
return false;
mark_compact_collector_ = nullptr;
}
+ delete incremental_marking_;
+ incremental_marking_ = nullptr;
+
delete gc_idle_time_handler_;
gc_idle_time_handler_ = nullptr;
#include "src/assert-scope.h"
#include "src/atomic-utils.h"
#include "src/globals.h"
-// TODO(mstarzinger): Three more includes to kill!
-#include "src/heap/incremental-marking.h"
+// TODO(mstarzinger): Two more includes to kill!
#include "src/heap/spaces.h"
#include "src/heap/store-buffer.h"
#include "src/list.h"
// Last hope GC, should try to squeeze as much as possible.
void CollectAllAvailableGarbage(const char* gc_reason = NULL);
+ // Reports and external memory pressure event, either performs a major GC or
+ // completes incremental marking in order to free external resources.
+ void ReportExternalMemoryPressure(const char* gc_reason = NULL);
+
// Invoked when GC was requested via the stack guard.
void HandleGCRequest();
GCCallbackFlags::kNoGCCallbackFlags,
const char* reason = nullptr);
- // Performs incremental marking steps of step_size_in_bytes as long as
- // deadline_ins_ms is not reached. step_size_in_bytes can be 0 to compute
- // an estimate increment. Returns the remaining time that cannot be used
- // for incremental marking anymore because a single step would exceed the
- // deadline.
- double AdvanceIncrementalMarking(
- intptr_t step_size_in_bytes, double deadline_in_ms,
- IncrementalMarking::StepActions step_actions);
-
void FinalizeIncrementalMarkingIfComplete(const char* comment);
bool TryFinalizeIdleIncrementalMarking(double idle_time_in_ms);
- IncrementalMarking* incremental_marking() { return &incremental_marking_; }
+ IncrementalMarking* incremental_marking() { return incremental_marking_; }
// ===========================================================================
// External string table API. ================================================
StoreBuffer store_buffer_;
- IncrementalMarking incremental_marking_;
+ IncrementalMarking* incremental_marking_;
GCIdleTimeHandler* gc_idle_time_handler_;
}
return kMoreWork;
}
- const double remaining_idle_time_in_ms = heap->AdvanceIncrementalMarking(
- 0, deadline_in_ms, IncrementalMarking::IdleStepActions());
+ const double remaining_idle_time_in_ms =
+ incremental_marking->AdvanceIncrementalMarking(
+ 0, deadline_in_ms, IncrementalMarking::IdleStepActions());
if (remaining_idle_time_in_ms > 0.0) {
heap->TryFinalizeIdleIncrementalMarking(remaining_idle_time_in_ms);
}
const int kIncrementalMarkingDelayMs = 50;
double deadline =
heap->MonotonicallyIncreasingTimeInMs() + kIncrementalMarkingDelayMs;
- heap->AdvanceIncrementalMarking(
+ heap->incremental_marking()->AdvanceIncrementalMarking(
0, deadline, i::IncrementalMarking::StepActions(
i::IncrementalMarking::NO_GC_VIA_STACK_GUARD,
i::IncrementalMarking::FORCE_MARKING,
#include "src/code-stubs.h"
#include "src/compilation-cache.h"
#include "src/conversions.h"
+#include "src/heap/gc-idle-time-handler.h"
#include "src/heap/gc-tracer.h"
#include "src/heap/mark-compact-inl.h"
#include "src/heap/objects-visiting.h"
}
+double IncrementalMarking::AdvanceIncrementalMarking(
+ intptr_t step_size_in_bytes, double deadline_in_ms,
+ IncrementalMarking::StepActions step_actions) {
+ DCHECK(!IsStopped());
+
+ if (step_size_in_bytes == 0) {
+ step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize(
+ static_cast<size_t>(GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs),
+ static_cast<size_t>(
+ heap()
+ ->tracer()
+ ->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()));
+ }
+
+ double remaining_time_in_ms = 0.0;
+ do {
+ Step(step_size_in_bytes, step_actions.completion_action,
+ step_actions.force_marking, step_actions.force_completion);
+ remaining_time_in_ms =
+ deadline_in_ms - heap()->MonotonicallyIncreasingTimeInMs();
+ } while (remaining_time_in_ms >=
+ 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs &&
+ !IsComplete() &&
+ !heap()->mark_compact_collector()->marking_deque()->IsEmpty());
+ return remaining_time_in_ms;
+}
+
+
void IncrementalMarking::OldSpaceStep(intptr_t allocated) {
if (IsStopped() && ShouldActivateEvenWithoutIdleNotification()) {
heap()->StartIncrementalMarking(Heap::kNoGCFlags, kNoGCCallbackFlags,
void Epilogue();
+ // Performs incremental marking steps of step_size_in_bytes as long as
+ // deadline_ins_ms is not reached. step_size_in_bytes can be 0 to compute
+ // an estimate increment. Returns the remaining time that cannot be used
+ // for incremental marking anymore because a single step would exceed the
+ // deadline.
+ double AdvanceIncrementalMarking(intptr_t step_size_in_bytes,
+ double deadline_in_ms,
+ StepActions step_actions);
+
// It's hard to know how much work the incremental marker should do to make
// progress in the face of the mutator creating new work for it. We start
// of at a moderate rate of work and gradually increase the speed of the
const int kIncrementalMarkingDelayMs = 500;
double deadline = heap()->MonotonicallyIncreasingTimeInMs() +
kIncrementalMarkingDelayMs;
- heap()->AdvanceIncrementalMarking(
+ heap()->incremental_marking()->AdvanceIncrementalMarking(
0, deadline, i::IncrementalMarking::StepActions(
i::IncrementalMarking::NO_GC_VIA_STACK_GUARD,
i::IncrementalMarking::FORCE_MARKING,
#include <algorithm>
#include "src/counters.h"
+#include "src/heap/incremental-marking.h"
#include "src/heap/store-buffer-inl.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
// Start incremental marking to active write barrier.
SimulateIncrementalMarking(heap, false);
- heap->AdvanceIncrementalMarking(10000000, 10000000,
- IncrementalMarking::IdleStepActions());
+ heap->incremental_marking()->AdvanceIncrementalMarking(
+ 10000000, 10000000, IncrementalMarking::IdleStepActions());
// Create references from the large object to the object on the evacuation
// candidate.