Commit 1d4c0532 authored by vegorov@chromium.org's avatar vegorov@chromium.org

Introduce kGCCallbackForced flag.

This flag will be passed to GC prologue/epilogue callbacks if GC was forced through GC extension.

BUG=
R=dcarney@chromium.org, mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/104023011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18558 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 21f1ca58
...@@ -3893,7 +3893,8 @@ enum GCType { ...@@ -3893,7 +3893,8 @@ enum GCType {
enum GCCallbackFlags { enum GCCallbackFlags {
kNoGCCallbackFlags = 0, kNoGCCallbackFlags = 0,
kGCCallbackFlagCompacted = 1 << 0, kGCCallbackFlagCompacted = 1 << 0,
kGCCallbackFlagConstructRetainedObjectInfos = 1 << 1 kGCCallbackFlagConstructRetainedObjectInfos = 1 << 1,
kGCCallbackFlagForced = 1 << 2
}; };
typedef void (*GCPrologueCallback)(GCType type, GCCallbackFlags flags); typedef void (*GCPrologueCallback)(GCType type, GCCallbackFlags flags);
......
...@@ -42,9 +42,11 @@ v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunctionTemplate( ...@@ -42,9 +42,11 @@ v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunctionTemplate(
void GCExtension::GC(const v8::FunctionCallbackInfo<v8::Value>& args) { void GCExtension::GC(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
if (args[0]->BooleanValue()) { if (args[0]->BooleanValue()) {
isolate->heap()->CollectGarbage(NEW_SPACE, "gc extension"); isolate->heap()->CollectGarbage(
NEW_SPACE, "gc extension", v8::kGCCallbackFlagForced);
} else { } else {
isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "gc extension"); isolate->heap()->CollectAllGarbage(
Heap::kNoGCFlags, "gc extension", v8::kGCCallbackFlagForced);
} }
} }
......
...@@ -532,10 +532,13 @@ void Heap::ScavengeObject(HeapObject** p, HeapObject* object) { ...@@ -532,10 +532,13 @@ void Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
} }
bool Heap::CollectGarbage(AllocationSpace space, const char* gc_reason) { bool Heap::CollectGarbage(AllocationSpace space,
const char* gc_reason,
const v8::GCCallbackFlags callbackFlags) {
const char* collector_reason = NULL; const char* collector_reason = NULL;
GarbageCollector collector = SelectGarbageCollector(space, &collector_reason); GarbageCollector collector = SelectGarbageCollector(space, &collector_reason);
return CollectGarbage(space, collector, gc_reason, collector_reason); return CollectGarbage(
space, collector, gc_reason, collector_reason, callbackFlags);
} }
......
...@@ -2128,7 +2128,7 @@ void NativeObjectsExplorer::FillRetainedObjects() { ...@@ -2128,7 +2128,7 @@ void NativeObjectsExplorer::FillRetainedObjects() {
group->info = NULL; // Acquire info object ownership. group->info = NULL; // Acquire info object ownership.
} }
isolate->global_handles()->RemoveObjectGroups(); isolate->global_handles()->RemoveObjectGroups();
isolate->heap()->CallGCEpilogueCallbacks(major_gc_type); isolate->heap()->CallGCEpilogueCallbacks(major_gc_type, kNoGCCallbackFlags);
// Record objects that are not in ObjectGroups, but have class ID. // Record objects that are not in ObjectGroups, but have class ID.
GlobalHandlesExtractor extractor(this); GlobalHandlesExtractor extractor(this);
isolate->global_handles()->IterateAllRootsWithClassIds(&extractor); isolate->global_handles()->IterateAllRootsWithClassIds(&extractor);
......
...@@ -702,12 +702,14 @@ void Heap::GarbageCollectionEpilogue() { ...@@ -702,12 +702,14 @@ void Heap::GarbageCollectionEpilogue() {
} }
void Heap::CollectAllGarbage(int flags, const char* gc_reason) { void Heap::CollectAllGarbage(int flags,
const char* gc_reason,
const v8::GCCallbackFlags gc_callback_flags) {
// Since we are ignoring the return value, the exact choice of space does // Since we are ignoring the return value, the exact choice of space does
// not matter, so long as we do not specify NEW_SPACE, which would not // not matter, so long as we do not specify NEW_SPACE, which would not
// cause a full GC. // cause a full GC.
mark_compact_collector_.SetFlags(flags); mark_compact_collector_.SetFlags(flags);
CollectGarbage(OLD_POINTER_SPACE, gc_reason); CollectGarbage(OLD_POINTER_SPACE, gc_reason, gc_callback_flags);
mark_compact_collector_.SetFlags(kNoGCFlags); mark_compact_collector_.SetFlags(kNoGCFlags);
} }
...@@ -750,7 +752,8 @@ void Heap::CollectAllAvailableGarbage(const char* gc_reason) { ...@@ -750,7 +752,8 @@ void Heap::CollectAllAvailableGarbage(const char* gc_reason) {
bool Heap::CollectGarbage(AllocationSpace space, bool Heap::CollectGarbage(AllocationSpace space,
GarbageCollector collector, GarbageCollector collector,
const char* gc_reason, const char* gc_reason,
const char* collector_reason) { const char* collector_reason,
const v8::GCCallbackFlags gc_callback_flags) {
// The VM is in the GC state until exiting this function. // The VM is in the GC state until exiting this function.
VMState<GC> state(isolate_); VMState<GC> state(isolate_);
...@@ -805,7 +808,7 @@ bool Heap::CollectGarbage(AllocationSpace space, ...@@ -805,7 +808,7 @@ bool Heap::CollectGarbage(AllocationSpace space,
(collector == SCAVENGER) ? isolate_->counters()->gc_scavenger() (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger()
: isolate_->counters()->gc_compactor()); : isolate_->counters()->gc_compactor());
next_gc_likely_to_collect_more = next_gc_likely_to_collect_more =
PerformGarbageCollection(collector, &tracer); PerformGarbageCollection(collector, &tracer, gc_callback_flags);
} }
GarbageCollectionEpilogue(); GarbageCollectionEpilogue();
...@@ -1032,8 +1035,10 @@ void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { ...@@ -1032,8 +1035,10 @@ void Heap::UpdateSurvivalRateTrend(int start_new_space_size) {
survival_rate_ = survival_rate; survival_rate_ = survival_rate;
} }
bool Heap::PerformGarbageCollection(GarbageCollector collector, bool Heap::PerformGarbageCollection(
GCTracer* tracer) { GarbageCollector collector,
GCTracer* tracer,
const v8::GCCallbackFlags gc_callback_flags) {
bool next_gc_likely_to_collect_more = false; bool next_gc_likely_to_collect_more = false;
if (collector != SCAVENGER) { if (collector != SCAVENGER) {
...@@ -1164,7 +1169,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector, ...@@ -1164,7 +1169,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
VMState<EXTERNAL> state(isolate_); VMState<EXTERNAL> state(isolate_);
HandleScope handle_scope(isolate_); HandleScope handle_scope(isolate_);
CallGCEpilogueCallbacks(gc_type); CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
} }
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
...@@ -1194,18 +1199,19 @@ void Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) { ...@@ -1194,18 +1199,19 @@ void Heap::CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags) {
} }
void Heap::CallGCEpilogueCallbacks(GCType gc_type) { void Heap::CallGCEpilogueCallbacks(GCType gc_type,
GCCallbackFlags gc_callback_flags) {
for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) {
if (gc_type & gc_epilogue_callbacks_[i].gc_type) { if (gc_type & gc_epilogue_callbacks_[i].gc_type) {
if (!gc_epilogue_callbacks_[i].pass_isolate_) { if (!gc_epilogue_callbacks_[i].pass_isolate_) {
v8::GCPrologueCallback callback = v8::GCPrologueCallback callback =
reinterpret_cast<v8::GCPrologueCallback>( reinterpret_cast<v8::GCPrologueCallback>(
gc_epilogue_callbacks_[i].callback); gc_epilogue_callbacks_[i].callback);
callback(gc_type, kNoGCCallbackFlags); callback(gc_type, gc_callback_flags);
} else { } else {
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate()); v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this->isolate());
gc_epilogue_callbacks_[i].callback( gc_epilogue_callbacks_[i].callback(
isolate, gc_type, kNoGCCallbackFlags); isolate, gc_type, gc_callback_flags);
} }
} }
} }
......
...@@ -1157,8 +1157,10 @@ class Heap { ...@@ -1157,8 +1157,10 @@ class Heap {
// Performs garbage collection operation. // Performs garbage collection operation.
// Returns whether there is a chance that another major GC could // Returns whether there is a chance that another major GC could
// collect more garbage. // collect more garbage.
inline bool CollectGarbage(AllocationSpace space, inline bool CollectGarbage(
const char* gc_reason = NULL); AllocationSpace space,
const char* gc_reason = NULL,
const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
static const int kNoGCFlags = 0; static const int kNoGCFlags = 0;
static const int kSweepPreciselyMask = 1; static const int kSweepPreciselyMask = 1;
...@@ -1173,7 +1175,10 @@ class Heap { ...@@ -1173,7 +1175,10 @@ class Heap {
// Performs a full garbage collection. If (flags & kMakeHeapIterableMask) is // Performs a full garbage collection. If (flags & kMakeHeapIterableMask) is
// non-zero, then the slower precise sweeper is used, which leaves the heap // non-zero, then the slower precise sweeper is used, which leaves the heap
// in a state where we can iterate over the heap visiting all objects. // in a state where we can iterate over the heap visiting all objects.
void CollectAllGarbage(int flags, const char* gc_reason = NULL); void CollectAllGarbage(
int flags,
const char* gc_reason = NULL,
const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
// Last hope GC, should try to squeeze as much as possible. // Last hope GC, should try to squeeze as much as possible.
void CollectAllAvailableGarbage(const char* gc_reason = NULL); void CollectAllAvailableGarbage(const char* gc_reason = NULL);
...@@ -1701,7 +1706,7 @@ class Heap { ...@@ -1701,7 +1706,7 @@ class Heap {
inline Isolate* isolate(); inline Isolate* isolate();
void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags); void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags);
void CallGCEpilogueCallbacks(GCType gc_type); void CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags);
inline bool OldGenerationAllocationLimitReached(); inline bool OldGenerationAllocationLimitReached();
...@@ -2052,16 +2057,20 @@ class Heap { ...@@ -2052,16 +2057,20 @@ class Heap {
// Performs garbage collection operation. // Performs garbage collection operation.
// Returns whether there is a chance that another major GC could // Returns whether there is a chance that another major GC could
// collect more garbage. // collect more garbage.
bool CollectGarbage(AllocationSpace space, bool CollectGarbage(
AllocationSpace space,
GarbageCollector collector, GarbageCollector collector,
const char* gc_reason, const char* gc_reason,
const char* collector_reason); const char* collector_reason,
const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
// Performs garbage collection // Performs garbage collection
// Returns whether there is a chance another major GC could // Returns whether there is a chance another major GC could
// collect more garbage. // collect more garbage.
bool PerformGarbageCollection(GarbageCollector collector, bool PerformGarbageCollection(
GCTracer* tracer); GarbageCollector collector,
GCTracer* tracer,
const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
inline void UpdateOldSpaceLimits(); inline void UpdateOldSpaceLimits();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment