Update the Idle collector to do a full GC
after being idle for some time. Remove the default argument from CollectAllGarbage. Review URL: http://codereview.chromium.org/174302 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2748 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
050d1297fa
commit
6f3c50460a
@ -2280,9 +2280,13 @@ class V8EXPORT V8 {
|
||||
/**
|
||||
* Optional notification that the embedder is idle.
|
||||
* V8 uses the notification to reduce memory footprint.
|
||||
* This call can be used repeatedly if the embedder remains idle.
|
||||
* \param is_high_priority tells whether the embedder is high priority.
|
||||
* Returns true if the embedder should stop calling IdleNotification
|
||||
* until real work has been done. This indicates that V8 has done
|
||||
* as much cleanup as it will be able to do.
|
||||
*/
|
||||
static void IdleNotification(bool is_high_priority);
|
||||
static bool IdleNotification(bool is_high_priority);
|
||||
|
||||
/**
|
||||
* Optional notification that the system is running low on memory.
|
||||
|
@ -2604,8 +2604,8 @@ bool v8::V8::Dispose() {
|
||||
}
|
||||
|
||||
|
||||
void v8::V8::IdleNotification(bool is_high_priority) {
|
||||
i::V8::IdleNotification(is_high_priority);
|
||||
bool v8::V8::IdleNotification(bool is_high_priority) {
|
||||
return i::V8::IdleNotification(is_high_priority);
|
||||
}
|
||||
|
||||
|
||||
@ -3335,7 +3335,7 @@ void V8::ResumeProfilerEx(int flags) {
|
||||
flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
|
||||
const int current_flags = i::Logger::GetActiveProfilerModules();
|
||||
i::Logger::ResumeProfiler(flags);
|
||||
i::Heap::CollectAllGarbage();
|
||||
i::Heap::CollectAllGarbage(false);
|
||||
i::Logger::PauseProfiler(~current_flags & flags);
|
||||
} else {
|
||||
i::Logger::ResumeProfiler(flags);
|
||||
|
@ -1548,8 +1548,8 @@ void Debug::CreateScriptCache() {
|
||||
// Perform two GCs to get rid of all unreferenced scripts. The first GC gets
|
||||
// rid of all the cached script wrappers and the second gets rid of the
|
||||
// scripts which is no longer referenced.
|
||||
Heap::CollectAllGarbage();
|
||||
Heap::CollectAllGarbage();
|
||||
Heap::CollectAllGarbage(false);
|
||||
Heap::CollectAllGarbage(false);
|
||||
|
||||
ASSERT(script_cache_ == NULL);
|
||||
script_cache_ = new ScriptCache();
|
||||
@ -1599,7 +1599,7 @@ Handle<FixedArray> Debug::GetLoadedScripts() {
|
||||
|
||||
// Perform GC to get unreferenced scripts evicted from the cache before
|
||||
// returning the content.
|
||||
Heap::CollectAllGarbage();
|
||||
Heap::CollectAllGarbage(false);
|
||||
|
||||
// Get the scripts from the cache.
|
||||
return script_cache_->GetScripts();
|
||||
|
@ -677,7 +677,7 @@ v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction(
|
||||
|
||||
v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) {
|
||||
// All allocation spaces other than NEW_SPACE have the same effect.
|
||||
Heap::CollectAllGarbage();
|
||||
Heap::CollectAllGarbage(false);
|
||||
return v8::Undefined();
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ int Heap::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
|
||||
amount_of_external_allocated_memory_ -
|
||||
amount_of_external_allocated_memory_at_last_global_gc_;
|
||||
if (amount_since_last_global_gc > external_allocation_limit_) {
|
||||
CollectAllGarbage();
|
||||
CollectAllGarbage(false);
|
||||
}
|
||||
} else {
|
||||
// Avoid underflow.
|
||||
@ -285,7 +285,7 @@ void Heap::SetLastScriptId(Object* last_script_id) {
|
||||
} \
|
||||
if (!__object__->IsRetryAfterGC()) RETURN_EMPTY; \
|
||||
Counters::gc_last_resort_from_handles.Increment(); \
|
||||
Heap::CollectAllGarbage(); \
|
||||
Heap::CollectAllGarbage(false); \
|
||||
{ \
|
||||
AlwaysAllocateScope __scope__; \
|
||||
__object__ = FUNCTION_CALL; \
|
||||
|
@ -332,7 +332,7 @@ void Heap::CollectAllGarbageIfContextDisposed() {
|
||||
// informed decisions about when to force a collection.
|
||||
if (!FLAG_expose_gc && context_disposed_pending_) {
|
||||
HistogramTimerScope scope(&Counters::gc_context);
|
||||
CollectAllGarbage();
|
||||
CollectAllGarbage(false);
|
||||
}
|
||||
context_disposed_pending_ = false;
|
||||
}
|
||||
|
35
src/heap.h
35
src/heap.h
@ -629,7 +629,7 @@ class Heap : public AllStatic {
|
||||
|
||||
// Performs a full garbage collection. Force compaction if the
|
||||
// parameter is true.
|
||||
static void CollectAllGarbage(bool force_compaction = false);
|
||||
static void CollectAllGarbage(bool force_compaction);
|
||||
|
||||
// Performs a full garbage collection if a context has been disposed
|
||||
// since the last time the check was performed.
|
||||
@ -842,6 +842,39 @@ class Heap : public AllStatic {
|
||||
> old_gen_allocation_limit_;
|
||||
}
|
||||
|
||||
// Can be called when the embedding application is idle.
|
||||
static bool IdleNotification() {
|
||||
static const int kIdlesBeforeCollection = 7;
|
||||
static int number_idle_notifications = 0;
|
||||
static int last_gc_count = gc_count_;
|
||||
|
||||
bool finished = false;
|
||||
|
||||
if (last_gc_count == gc_count_) {
|
||||
number_idle_notifications++;
|
||||
} else {
|
||||
number_idle_notifications = 0;
|
||||
last_gc_count = gc_count_;
|
||||
}
|
||||
|
||||
if (number_idle_notifications >= kIdlesBeforeCollection) {
|
||||
// The first time through we collect without forcing compaction.
|
||||
// The second time through we force compaction and quit.
|
||||
bool force_compaction =
|
||||
number_idle_notifications > kIdlesBeforeCollection;
|
||||
CollectAllGarbage(force_compaction);
|
||||
last_gc_count = gc_count_;
|
||||
if (force_compaction) {
|
||||
number_idle_notifications = 0;
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Uncommit unused memory in new space.
|
||||
Heap::UncommitFromSpace();
|
||||
return finished;
|
||||
}
|
||||
|
||||
// Declare all the root indices.
|
||||
enum RootListIndex {
|
||||
#define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex,
|
||||
|
@ -171,7 +171,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
// Get rid of unreferenced scripts with a global GC.
|
||||
i::Heap::CollectAllGarbage();
|
||||
i::Heap::CollectAllGarbage(false);
|
||||
i::Serializer ser;
|
||||
ser.Serialize();
|
||||
v8::internal::byte* bytes;
|
||||
|
@ -7263,7 +7263,7 @@ static Object* Runtime_DebugReferencedBy(Arguments args) {
|
||||
ASSERT(args.length() == 3);
|
||||
|
||||
// First perform a full GC in order to avoid references from dead objects.
|
||||
Heap::CollectAllGarbage();
|
||||
Heap::CollectAllGarbage(false);
|
||||
|
||||
// Check parameters.
|
||||
CONVERT_CHECKED(JSObject, target, args[0]);
|
||||
@ -7339,7 +7339,7 @@ static Object* Runtime_DebugConstructedBy(Arguments args) {
|
||||
ASSERT(args.length() == 2);
|
||||
|
||||
// First perform a full GC in order to avoid dead objects.
|
||||
Heap::CollectAllGarbage();
|
||||
Heap::CollectAllGarbage(false);
|
||||
|
||||
// Check parameters.
|
||||
CONVERT_CHECKED(JSFunction, constructor, args[0]);
|
||||
@ -7633,7 +7633,7 @@ void Runtime::PerformGC(Object* result) {
|
||||
// Handle last resort GC and make sure to allow future allocations
|
||||
// to grow the heap without causing GCs (if possible).
|
||||
Counters::gc_last_resort_from_js.Increment();
|
||||
Heap::CollectAllGarbage();
|
||||
Heap::CollectAllGarbage(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
10
src/v8.cc
10
src/v8.cc
@ -157,13 +157,13 @@ uint32_t V8::Random() {
|
||||
}
|
||||
|
||||
|
||||
void V8::IdleNotification(bool is_high_priority) {
|
||||
if (!FLAG_use_idle_notification) return;
|
||||
bool V8::IdleNotification(bool is_high_priority) {
|
||||
if (!FLAG_use_idle_notification) return false;
|
||||
// Ignore high priority instances of V8.
|
||||
if (is_high_priority) return;
|
||||
if (is_high_priority) return false;
|
||||
|
||||
// Uncommit unused memory in new space.
|
||||
Heap::UncommitFromSpace();
|
||||
// Tell the heap that it may want to adjust.
|
||||
return Heap::IdleNotification();
|
||||
}
|
||||
|
||||
|
||||
|
2
src/v8.h
2
src/v8.h
@ -100,7 +100,7 @@ class V8 : public AllStatic {
|
||||
static Smi* RandomPositiveSmi();
|
||||
|
||||
// Idle notification directly from the API.
|
||||
static void IdleNotification(bool is_high_priority);
|
||||
static bool IdleNotification(bool is_high_priority);
|
||||
|
||||
private:
|
||||
// True if engine is currently running
|
||||
|
Loading…
Reference in New Issue
Block a user