heap: Rework forced GCs
Forced GCs can either be invoked internally or communicate the fact that they are forced externally via API. Before this CL, all uses were passing kGCCallbackFlagForced to indicate that the GC was forced. This flag is used by embedders though to trigger followup actions. E.g., it can be used to trigger a follow up call to GarbageCollectionForTesting() call which requires --expose-gc. This patch changes the semantics as follows: - Internal forced GCs use a Heap GC flag (kForcedGC) - External forced GCs and GC extension use kGCCallbackFlagForced Bug: chromium:1074061 Change-Id: Ide7ea0ccdf88b8c8cac002289aef5b7eb0f9748c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2172747 Reviewed-by: Maya Lekova <mslekova@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#67498}
This commit is contained in:
parent
3afa7cf0d3
commit
fe0c91cb6c
@ -534,8 +534,7 @@ bool CompilationDependencies::Commit(Handle<Code> code) {
|
|||||||
// that triggers its deoptimization.
|
// that triggers its deoptimization.
|
||||||
if (FLAG_stress_gc_during_compilation) {
|
if (FLAG_stress_gc_during_compilation) {
|
||||||
broker_->isolate()->heap()->PreciseCollectAllGarbage(
|
broker_->isolate()->heap()->PreciseCollectAllGarbage(
|
||||||
Heap::kNoGCFlags, GarbageCollectionReason::kTesting,
|
Heap::kForcedGC, GarbageCollectionReason::kTesting, kNoGCCallbackFlags);
|
||||||
kGCCallbackFlagForced);
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
for (auto dep : dependencies_) {
|
for (auto dep : dependencies_) {
|
||||||
|
@ -1380,16 +1380,15 @@ void Heap::CollectAllAvailableGarbage(GarbageCollectionReason gc_reason) {
|
|||||||
// The optimizing compiler may be unnecessarily holding on to memory.
|
// The optimizing compiler may be unnecessarily holding on to memory.
|
||||||
isolate()->AbortConcurrentOptimization(BlockingBehavior::kDontBlock);
|
isolate()->AbortConcurrentOptimization(BlockingBehavior::kDontBlock);
|
||||||
isolate()->ClearSerializerData();
|
isolate()->ClearSerializerData();
|
||||||
set_current_gc_flags(kReduceMemoryFootprintMask);
|
set_current_gc_flags(
|
||||||
|
kReduceMemoryFootprintMask |
|
||||||
|
(gc_reason == GarbageCollectionReason::kLowMemoryNotification ? kForcedGC
|
||||||
|
: 0));
|
||||||
isolate_->compilation_cache()->Clear();
|
isolate_->compilation_cache()->Clear();
|
||||||
const int kMaxNumberOfAttempts = 7;
|
const int kMaxNumberOfAttempts = 7;
|
||||||
const int kMinNumberOfAttempts = 2;
|
const int kMinNumberOfAttempts = 2;
|
||||||
const v8::GCCallbackFlags callback_flags =
|
|
||||||
gc_reason == GarbageCollectionReason::kLowMemoryNotification
|
|
||||||
? v8::kGCCallbackFlagForced
|
|
||||||
: v8::kGCCallbackFlagCollectAllAvailableGarbage;
|
|
||||||
for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
|
for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
|
||||||
if (!CollectGarbage(OLD_SPACE, gc_reason, callback_flags) &&
|
if (!CollectGarbage(OLD_SPACE, gc_reason, kNoGCCallbackFlags) &&
|
||||||
attempt + 1 >= kMinNumberOfAttempts) {
|
attempt + 1 >= kMinNumberOfAttempts) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1512,7 +1511,8 @@ bool Heap::CollectGarbage(AllocationSpace space,
|
|||||||
const v8::GCCallbackFlags gc_callback_flags) {
|
const v8::GCCallbackFlags gc_callback_flags) {
|
||||||
const char* collector_reason = nullptr;
|
const char* collector_reason = nullptr;
|
||||||
GarbageCollector collector = SelectGarbageCollector(space, &collector_reason);
|
GarbageCollector collector = SelectGarbageCollector(space, &collector_reason);
|
||||||
is_current_gc_forced_ = gc_callback_flags & v8::kGCCallbackFlagForced;
|
is_current_gc_forced_ = gc_callback_flags & v8::kGCCallbackFlagForced ||
|
||||||
|
current_gc_flags_ & kForcedGC;
|
||||||
|
|
||||||
DevToolsTraceEventScope devtools_trace_event_scope(
|
DevToolsTraceEventScope devtools_trace_event_scope(
|
||||||
this, IsYoungGenerationCollector(collector) ? "MinorGC" : "MajorGC",
|
this, IsYoungGenerationCollector(collector) ? "MinorGC" : "MajorGC",
|
||||||
|
@ -300,6 +300,9 @@ class Heap {
|
|||||||
|
|
||||||
static const int kNoGCFlags = 0;
|
static const int kNoGCFlags = 0;
|
||||||
static const int kReduceMemoryFootprintMask = 1;
|
static const int kReduceMemoryFootprintMask = 1;
|
||||||
|
// GCs that are forced, either through testing configurations (requring
|
||||||
|
// --expose-gc) or through DevTools (using LowMemoryNotificaton).
|
||||||
|
static const int kForcedGC = 2;
|
||||||
|
|
||||||
// The minimum size of a HeapObject on the heap.
|
// The minimum size of a HeapObject on the heap.
|
||||||
static const int kMinObjectSizeInTaggedWords = 2;
|
static const int kMinObjectSizeInTaggedWords = 2;
|
||||||
|
@ -265,8 +265,8 @@ auto Engine::make(own<Config>&& config) -> own<Engine> {
|
|||||||
StoreImpl::~StoreImpl() {
|
StoreImpl::~StoreImpl() {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
reinterpret_cast<i::Isolate*>(isolate_)->heap()->PreciseCollectAllGarbage(
|
reinterpret_cast<i::Isolate*>(isolate_)->heap()->PreciseCollectAllGarbage(
|
||||||
i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
|
i::Heap::kForcedGC, i::GarbageCollectionReason::kTesting,
|
||||||
v8::kGCCallbackFlagForced);
|
v8::kNoGCCallbackFlags);
|
||||||
#endif
|
#endif
|
||||||
context()->Exit();
|
context()->Exit();
|
||||||
isolate_->Dispose();
|
isolate_->Dispose();
|
||||||
|
@ -26850,8 +26850,8 @@ static void CallIsolate2(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||||||
v8::Local<v8::Context>::New(isolate_2, context_2);
|
v8::Local<v8::Context>::New(isolate_2, context_2);
|
||||||
v8::Context::Scope context_scope(context);
|
v8::Context::Scope context_scope(context);
|
||||||
reinterpret_cast<i::Isolate*>(isolate_2)->heap()->CollectAllGarbage(
|
reinterpret_cast<i::Isolate*>(isolate_2)->heap()->CollectAllGarbage(
|
||||||
i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
|
i::Heap::kForcedGC, i::GarbageCollectionReason::kTesting,
|
||||||
v8::kGCCallbackFlagForced);
|
v8::kNoGCCallbackFlags);
|
||||||
CompileRun("f2() //# sourceURL=isolate2b");
|
CompileRun("f2() //# sourceURL=isolate2b");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ own<Trap> Stage4_GC(void* env, const Val args[], Val results[]) {
|
|||||||
printf("Stage4...\n");
|
printf("Stage4...\n");
|
||||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env);
|
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env);
|
||||||
isolate->heap()->PreciseCollectAllGarbage(
|
isolate->heap()->PreciseCollectAllGarbage(
|
||||||
i::Heap::kNoGCFlags, i::GarbageCollectionReason::kTesting,
|
i::Heap::kForcedGC, i::GarbageCollectionReason::kTesting,
|
||||||
v8::kGCCallbackFlagForced);
|
v8::kNoGCCallbackFlags);
|
||||||
results[0] = Val::i32(args[0].i32() + 1);
|
results[0] = Val::i32(args[0].i32() + 1);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user