Commit 21833093 authored by ager@chromium.org's avatar ager@chromium.org

Introduce a external allocation limit.

If V8 is holding on to a lot of external memory, we attempt to clean
it up even if we do not get an allocation failure.  Since tiny V8
objects can hold on to a lot of external memory, we might run out of
external memory while waiting for a normal allocation failure.
Review URL: http://codereview.chromium.org/155916

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2519 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent be562ee7
......@@ -228,6 +228,31 @@ void Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
}
int Heap::AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
ASSERT(HasBeenSetup());
int amount = amount_of_external_allocated_memory_ + change_in_bytes;
if (change_in_bytes >= 0) {
// Avoid overflow.
if (amount > amount_of_external_allocated_memory_) {
amount_of_external_allocated_memory_ = amount;
}
int amount_since_last_global_gc =
amount_of_external_allocated_memory_ -
amount_of_external_allocated_memory_at_last_global_gc_;
if (amount_since_last_global_gc > external_allocation_limit_) {
CollectAllGarbage();
}
} else {
// Avoid underflow.
if (amount >= 0) {
amount_of_external_allocated_memory_ = amount;
}
}
ASSERT(amount_of_external_allocated_memory_ >= 0);
return amount_of_external_allocated_memory_;
}
void Heap::SetLastScriptId(Object* last_script_id) {
roots_[kLastScriptIdRootIndex] = last_script_id;
}
......
......@@ -85,8 +85,8 @@ GCCallback Heap::global_gc_epilogue_callback_ = NULL;
// Variables set based on semispace_size_ and old_generation_size_ in
// ConfigureHeap.
int Heap::young_generation_size_ = 0; // Will be 2 * semispace_size_.
int Heap::survived_since_last_expansion_ = 0;
int Heap::external_allocation_limit_ = 0;
Heap::HeapState Heap::gc_state_ = NOT_IN_GC;
......@@ -2988,6 +2988,7 @@ bool Heap::ConfigureHeap(int semispace_size, int old_gen_size) {
semispace_size_ = RoundUpToPowerOf2(semispace_size_);
initial_semispace_size_ = Min(initial_semispace_size_, semispace_size_);
young_generation_size_ = 2 * semispace_size_;
external_allocation_limit_ = 10 * semispace_size_;
// The old generation is paged.
old_generation_size_ = RoundUp(old_generation_size_, Page::kPageSize);
......
......@@ -746,7 +746,7 @@ class Heap : public AllStatic {
static Object* CreateSymbol(String* str);
// Write barrier support for address[offset] = o.
inline static void RecordWrite(Address address, int offset);
static inline void RecordWrite(Address address, int offset);
// Given an address occupied by a live code object, return that object.
static Object* FindCodeObject(Address a);
......@@ -802,22 +802,7 @@ class Heap : public AllStatic {
// Adjusts the amount of registered external memory.
// Returns the adjusted value.
static int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes) {
int amount = amount_of_external_allocated_memory_ + change_in_bytes;
if (change_in_bytes >= 0) {
// Avoid overflow.
if (amount > amount_of_external_allocated_memory_) {
amount_of_external_allocated_memory_ = amount;
}
} else {
// Avoid underflow.
if (amount >= 0) {
amount_of_external_allocated_memory_ = amount;
}
}
ASSERT(amount_of_external_allocated_memory_ >= 0);
return amount_of_external_allocated_memory_;
}
static inline int AdjustAmountOfExternalAllocatedMemory(int change_in_bytes);
// Allocate unitialized fixed array (pretenure == NON_TENURE).
static Object* AllocateRawFixedArray(int length);
......@@ -901,6 +886,10 @@ class Heap : public AllStatic {
// every allocation in large object space.
static int old_gen_allocation_limit_;
// Limit on the amount of externally allocated memory allowed
// between global GCs. If reached a global GC is forced.
static int external_allocation_limit_;
// The amount of external memory registered through the API kept alive
// by global handles
static int amount_of_external_allocated_memory_;
......@@ -1230,7 +1219,7 @@ class KeyedLookupCache {
// Clear the cache.
static void Clear();
private:
inline static int Hash(Map* map, String* name);
static inline int Hash(Map* map, String* name);
static const int kLength = 64;
struct Key {
Map* map;
......
......@@ -6216,6 +6216,7 @@ THREADED_TEST(NestedHandleScopeAndContexts) {
THREADED_TEST(ExternalAllocatedMemory) {
v8::HandleScope outer;
v8::Persistent<Context> env = Context::New();
const int kSize = 1024*1024;
CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize), kSize);
CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize), 0);
......
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