From a83b1b9cb3114308ee59b842570787a9c0005b0c Mon Sep 17 00:00:00 2001 From: "jochen@chromium.org" Date: Thu, 5 Jun 2014 08:44:42 +0000 Subject: [PATCH] Move most of the implementation of AdjustAmountOfExternalMemory to v8.h This reduces the overhead of reporting allocations to v8 to an acceptable level. BUG=none LOG=n R=dcarney@chromium.org, hpayer@chromium.org Review URL: https://codereview.chromium.org/310393003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21688 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 39 +++++++++++++++++++++++++++++++++++++-- src/api.cc | 7 +++---- src/flag-definitions.h | 3 --- src/heap-inl.h | 42 ------------------------------------------ src/heap.cc | 14 ++++---------- src/heap.h | 23 +++++++---------------- src/isolate.cc | 7 +++++++ src/runtime.cc | 8 +++++--- 8 files changed, 63 insertions(+), 80 deletions(-) diff --git a/include/v8.h b/include/v8.h index c895c88..071ea33 100644 --- a/include/v8.h +++ b/include/v8.h @@ -4215,7 +4215,8 @@ class V8_EXPORT Isolate { * kept alive by JavaScript objects. * \returns the adjusted value. */ - int64_t AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes); + V8_INLINE int64_t + AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes); /** * Returns heap profiler for this isolate. Will return NULL until the isolate @@ -4418,6 +4419,7 @@ class V8_EXPORT Isolate { 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); }; class V8_EXPORT StartupData { @@ -5446,6 +5448,7 @@ namespace internal { const int kApiPointerSize = sizeof(void*); // NOLINT const int kApiIntSize = sizeof(int); // NOLINT +const int kApiInt64Size = sizeof(int64_t); // NOLINT // Tag information for HeapObject. const int kHeapObjectTag = 1; @@ -5544,13 +5547,23 @@ class Internals { static const int kExternalAsciiRepresentationTag = 0x06; static const int kIsolateEmbedderDataOffset = 0 * kApiPointerSize; - static const int kIsolateRootsOffset = 5 * kApiPointerSize; + static const int kAmountOfExternalAllocatedMemoryOffset = + 4 * kApiPointerSize; + static const int kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset = + kAmountOfExternalAllocatedMemoryOffset + kApiInt64Size; + static const int kIsolateRootsOffset = + kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset + kApiInt64Size + + kApiPointerSize; static const int kUndefinedValueRootIndex = 5; static const int kNullValueRootIndex = 7; static const int kTrueValueRootIndex = 8; static const int kFalseValueRootIndex = 9; static const int kEmptyStringRootIndex = 162; + // The external allocation limit should be below 256 MB on all architectures + // to avoid that resource-constrained embedders run low on memory. + static const int kExternalAllocationLimit = 192 * 1024 * 1024; + static const int kNodeClassIdOffset = 1 * kApiPointerSize; static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3; static const int kNodeStateMask = 0xf; @@ -6570,6 +6583,28 @@ uint32_t Isolate::GetNumberOfDataSlots() { } +int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( + int64_t change_in_bytes) { + typedef internal::Internals I; + int64_t* amount_of_external_allocated_memory = + reinterpret_cast(reinterpret_cast(this) + + I::kAmountOfExternalAllocatedMemoryOffset); + int64_t* amount_of_external_allocated_memory_at_last_global_gc = + reinterpret_cast( + reinterpret_cast(this) + + I::kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset); + int64_t amount = *amount_of_external_allocated_memory + change_in_bytes; + if (change_in_bytes > 0 && + amount - *amount_of_external_allocated_memory_at_last_global_gc > + I::kExternalAllocationLimit) { + CollectAllGarbage("external memory allocation limit reached."); + } else { + *amount_of_external_allocated_memory = amount; + } + return *amount_of_external_allocated_memory; +} + + template void Isolate::SetObjectGroupId(const Persistent& object, UniqueId id) { diff --git a/src/api.cc b/src/api.cc index 931b6ae..a3b1b1d 100644 --- a/src/api.cc +++ b/src/api.cc @@ -6305,10 +6305,9 @@ void V8::SetFailedAccessCheckCallbackFunction( } -int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( - int64_t change_in_bytes) { - i::Heap* heap = reinterpret_cast(this)->heap(); - return heap->AdjustAmountOfExternalAllocatedMemory(change_in_bytes); +void Isolate::CollectAllGarbage(const char* gc_reason) { + reinterpret_cast(this)->heap()->CollectAllGarbage( + i::Heap::kNoGCFlags, gc_reason); } diff --git a/src/flag-definitions.h b/src/flag-definitions.h index cd08378..3efc799 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -494,9 +494,6 @@ DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") -DEFINE_bool(trace_external_memory, false, - "print amount of external allocated memory after each time " - "it is adjusted.") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(weak_embedded_maps_in_ic, true, diff --git a/src/heap-inl.h b/src/heap-inl.h index c697fed..64125bc 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -527,48 +527,6 @@ bool Heap::CollectGarbage(AllocationSpace space, } -int64_t Heap::AdjustAmountOfExternalAllocatedMemory( - int64_t change_in_bytes) { - ASSERT(HasBeenSetUp()); - int64_t 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 { - // Give up and reset the counters in case of an overflow. - amount_of_external_allocated_memory_ = 0; - amount_of_external_allocated_memory_at_last_global_gc_ = 0; - } - int64_t amount_since_last_global_gc = PromotedExternalMemorySize(); - if (amount_since_last_global_gc > external_allocation_limit_) { - CollectAllGarbage(kNoGCFlags, "external memory allocation limit reached"); - } - } else { - // Avoid underflow. - if (amount >= 0) { - amount_of_external_allocated_memory_ = amount; - } else { - // Give up and reset the counters in case of an underflow. - amount_of_external_allocated_memory_ = 0; - amount_of_external_allocated_memory_at_last_global_gc_ = 0; - } - } - if (FLAG_trace_external_memory) { - PrintPID("%8.0f ms: ", isolate()->time_millis_since_init()); - PrintF("Adjust amount of external memory: delta=%6" V8_PTR_PREFIX "d KB, " - "amount=%6" V8_PTR_PREFIX "d KB, since_gc=%6" V8_PTR_PREFIX "d KB, " - "isolate=0x%08" V8PRIxPTR ".\n", - static_cast(change_in_bytes / KB), - static_cast(amount_of_external_allocated_memory_ / KB), - static_cast(PromotedExternalMemorySize() / KB), - reinterpret_cast(isolate())); - } - ASSERT(amount_of_external_allocated_memory_ >= 0); - return amount_of_external_allocated_memory_; -} - - Isolate* Heap::isolate() { return reinterpret_cast(reinterpret_cast(this) - reinterpret_cast(reinterpret_cast(4)->heap()) + 4); diff --git a/src/heap.cc b/src/heap.cc index 5198ab5..1b2d17c 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -44,7 +44,9 @@ namespace internal { Heap::Heap() - : isolate_(NULL), + : amount_of_external_allocated_memory_(0), + amount_of_external_allocated_memory_at_last_global_gc_(0), + isolate_(NULL), code_range_size_(0), // semispace_size_ should be a power of 2 and old_generation_size_ should be // a multiple of Page::kPageSize. @@ -54,7 +56,7 @@ Heap::Heap() max_old_generation_size_(700ul * (kPointerSize / 4) * MB), max_executable_size_(256ul * (kPointerSize / 4) * MB), // Variables set based on semispace_size_ and old_generation_size_ in -// ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) +// ConfigureHeap. // Will be 4 * reserved_semispace_size_ to ensure that young // generation can be aligned to its size. maximum_committed_(0), @@ -86,9 +88,6 @@ Heap::Heap() #endif // DEBUG old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit), size_of_old_gen_at_last_old_space_gc_(0), - external_allocation_limit_(0), - amount_of_external_allocated_memory_(0), - amount_of_external_allocated_memory_at_last_global_gc_(0), old_gen_exhausted_(false), inline_allocation_disabled_(false), store_buffer_rebuilder_(store_buffer()), @@ -5010,11 +5009,6 @@ bool Heap::ConfigureHeap(int max_semi_space_size, initial_semispace_size_ = Min(initial_semispace_size_, max_semi_space_size_); - // The external allocation limit should be below 256 MB on all architectures - // to avoid that resource-constrained embedders run low on memory. - external_allocation_limit_ = 192 * MB; - ASSERT(external_allocation_limit_ <= 256 * MB); - // The old generation is paged and needs at least one page for each space. int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1; max_old_generation_size_ = diff --git a/src/heap.h b/src/heap.h index e9747df..6972ca7 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1036,11 +1036,6 @@ class Heap { void CreateApiObjects(); - // Adjusts the amount of registered external memory. - // Returns the adjusted value. - inline int64_t AdjustAmountOfExternalAllocatedMemory( - int64_t change_in_bytes); - inline intptr_t PromotedTotalSize() { int64_t total = PromotedSpaceSizeOfObjects() + PromotedExternalMemorySize(); if (total > kMaxInt) return static_cast(kMaxInt); @@ -1500,6 +1495,13 @@ class Heap { private: Heap(); + // The amount of external memory registered through the API kept alive + // by global handles + int64_t amount_of_external_allocated_memory_; + + // Caches the amount of external memory registered at the last global gc. + int64_t amount_of_external_allocated_memory_at_last_global_gc_; + // This can be calculated directly from a pointer to the heap; however, it is // more expedient to get at the isolate directly from within Heap methods. Isolate* isolate_; @@ -1590,17 +1592,6 @@ class Heap { // Used to adjust the limits that control the timing of the next GC. intptr_t size_of_old_gen_at_last_old_space_gc_; - // Limit on the amount of externally allocated memory allowed - // between global GCs. If reached a global GC is forced. - intptr_t external_allocation_limit_; - - // The amount of external memory registered through the API kept alive - // by global handles - int64_t amount_of_external_allocated_memory_; - - // Caches the amount of external memory registered at the last global gc. - int64_t amount_of_external_allocated_memory_at_last_global_gc_; - // Indicates that an allocation has failed in the old generation since the // last GC. bool old_gen_exhausted_; diff --git a/src/isolate.cc b/src/isolate.cc index 7e60566..cc968bb 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -1963,6 +1963,13 @@ bool Isolate::Init(Deserializer* des) { Internals::kIsolateEmbedderDataOffset); CHECK_EQ(static_cast(OFFSET_OF(Isolate, heap_.roots_)), Internals::kIsolateRootsOffset); + CHECK_EQ(static_cast( + OFFSET_OF(Isolate, heap_.amount_of_external_allocated_memory_)), + Internals::kAmountOfExternalAllocatedMemoryOffset); + CHECK_EQ(static_cast(OFFSET_OF( + Isolate, + heap_.amount_of_external_allocated_memory_at_last_global_gc_)), + Internals::kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset); state_ = INITIALIZED; time_millis_at_init_ = OS::TimeCurrentMillis(); diff --git a/src/runtime.cc b/src/runtime.cc index fdc6bf9..e5966ef 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -764,8 +764,9 @@ void Runtime::FreeArrayBuffer(Isolate* isolate, size_t allocated_length = NumberToSize( isolate, phantom_array_buffer->byte_length()); - isolate->heap()->AdjustAmountOfExternalAllocatedMemory( - -static_cast(allocated_length)); + reinterpret_cast(isolate) + ->AdjustAmountOfExternalAllocatedMemory( + -static_cast(allocated_length)); CHECK(V8::ArrayBufferAllocator() != NULL); V8::ArrayBufferAllocator()->Free( phantom_array_buffer->backing_store(), @@ -819,7 +820,8 @@ bool Runtime::SetupArrayBufferAllocatingData( SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length); - isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); + reinterpret_cast(isolate) + ->AdjustAmountOfExternalAllocatedMemory(allocated_length); return true; } -- 2.7.4