Move most of the implementation of AdjustAmountOfExternalMemory to v8.h
authorjochen@chromium.org <jochen@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 5 Jun 2014 08:44:42 +0000 (08:44 +0000)
committerjochen@chromium.org <jochen@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 5 Jun 2014 08:44:42 +0000 (08:44 +0000)
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
src/api.cc
src/flag-definitions.h
src/heap-inl.h
src/heap.cc
src/heap.h
src/isolate.cc
src/runtime.cc

index c895c88..071ea33 100644 (file)
@@ -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<int64_t*>(reinterpret_cast<uint8_t*>(this) +
+                                 I::kAmountOfExternalAllocatedMemoryOffset);
+  int64_t* amount_of_external_allocated_memory_at_last_global_gc =
+      reinterpret_cast<int64_t*>(
+          reinterpret_cast<uint8_t*>(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<typename T>
 void Isolate::SetObjectGroupId(const Persistent<T>& object,
                                UniqueId id) {
index 931b6ae..a3b1b1d 100644 (file)
@@ -6305,10 +6305,9 @@ void V8::SetFailedAccessCheckCallbackFunction(
 }
 
 
-int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
-    int64_t change_in_bytes) {
-  i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
-  return heap->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
+void Isolate::CollectAllGarbage(const char* gc_reason) {
+  reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
+      i::Heap::kNoGCFlags, gc_reason);
 }
 
 
index cd08378..3efc799 100644 (file)
@@ -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,
index c697fed..64125bc 100644 (file)
@@ -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<intptr_t>(change_in_bytes / KB),
-           static_cast<intptr_t>(amount_of_external_allocated_memory_ / KB),
-           static_cast<intptr_t>(PromotedExternalMemorySize() / KB),
-           reinterpret_cast<intptr_t>(isolate()));
-  }
-  ASSERT(amount_of_external_allocated_memory_ >= 0);
-  return amount_of_external_allocated_memory_;
-}
-
-
 Isolate* Heap::isolate() {
   return reinterpret_cast<Isolate*>(reinterpret_cast<intptr_t>(this) -
       reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4);
index 5198ab5..1b2d17c 100644 (file)
@@ -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_ =
index e9747df..6972ca7 100644 (file)
@@ -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<intptr_t>(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_;
index 7e60566..cc968bb 100644 (file)
@@ -1963,6 +1963,13 @@ bool Isolate::Init(Deserializer* des) {
            Internals::kIsolateEmbedderDataOffset);
   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.roots_)),
            Internals::kIsolateRootsOffset);
+  CHECK_EQ(static_cast<int>(
+               OFFSET_OF(Isolate, heap_.amount_of_external_allocated_memory_)),
+           Internals::kAmountOfExternalAllocatedMemoryOffset);
+  CHECK_EQ(static_cast<int>(OFFSET_OF(
+               Isolate,
+               heap_.amount_of_external_allocated_memory_at_last_global_gc_)),
+           Internals::kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset);
 
   state_ = INITIALIZED;
   time_millis_at_init_ = OS::TimeCurrentMillis();
index fdc6bf9..e5966ef 100644 (file)
@@ -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<int64_t>(allocated_length));
+  reinterpret_cast<v8::Isolate*>(isolate)
+      ->AdjustAmountOfExternalAllocatedMemory(
+          -static_cast<int64_t>(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<v8::Isolate*>(isolate)
+      ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
 
   return true;
 }