Reviewers: Hannes Payer,

Description:
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
[email protected]

Please review this at https://codereview.chromium.org/310393003/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+71, -24 lines):
  M include/v8.h
  M src/api.cc
  M src/heap.h
  M src/heap.cc
  M src/heap-inl.h
  M src/isolate.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index b1da55e2c5ee0d2cf566c976b95dde2e0396a27b..0c049bda6cae648ef389b49961aa87f398a0b0de 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);
+ int64_t SlowAdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes);
 };

 class V8_EXPORT StartupData {
@@ -5464,6 +5466,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;
@@ -5562,7 +5565,11 @@ class Internals {
   static const int kExternalAsciiRepresentationTag = 0x06;

   static const int kIsolateEmbedderDataOffset = 0 * kApiPointerSize;
-  static const int kIsolateRootsOffset = 5 * kApiPointerSize;
+ static const int kAmountOfExternalAllocatedMemoryOffset = 5 * kApiPointerSize;
+  static const int kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset =
+      5 * kApiPointerSize + kApiInt64Size;
+  static const int kIsolateRootsOffset =
+      5 * kApiPointerSize + 2 * kApiInt64Size;
   static const int kUndefinedValueRootIndex = 5;
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
@@ -6588,6 +6595,49 @@ uint32_t Isolate::GetNumberOfDataSlots() {
 }


+int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
+    int64_t change_in_bytes) {
+#ifndef V8_ENABLE_CHECKS
+  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) {
+    // Avoid overflow.
+    if (amount > *amount_of_external_allocated_memory) {
+      if (amount - *amount_of_external_allocated_memory_at_last_global_gc >
+          192 * 1024 * 1024) {
+        // Will likely trigger a GC.
+        return SlowAdjustAmountOfExternalAllocatedMemory(change_in_bytes);
+      }
+      *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;
+    }
+  } 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;
+    }
+  }
+  return *amount_of_external_allocated_memory;
+#else
+  return SlowAdjustAmountOfExternalAllocatedMemory(change_in_bytes);
+#endif
+}
+
+
 template<typename T>
 void Isolate::SetObjectGroupId(const Persistent<T>& object,
                                UniqueId id) {
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index 9f8103c5c5a92b243c42901287698fd57a239110..72df170955c1dc590ee1ebab1b6d7ac01721ff59 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -6321,7 +6321,7 @@ void V8::SetFailedAccessCheckCallbackFunction(
 }


-int64_t Isolate::AdjustAmountOfExternalAllocatedMemory(
+int64_t Isolate::SlowAdjustAmountOfExternalAllocatedMemory(
     int64_t change_in_bytes) {
   i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
   return heap->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
Index: src/heap-inl.h
diff --git a/src/heap-inl.h b/src/heap-inl.h
index c697fedfdaac2d44da510712ef4e9fcc16df1e74..6dce95095d9b986277866669a11195f1d268aa71 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -541,7 +541,7 @@ int64_t Heap::AdjustAmountOfExternalAllocatedMemory(
       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_) {
+    if (amount_since_last_global_gc > 192 * MB) {
CollectAllGarbage(kNoGCFlags, "external memory allocation limit reached");
     }
   } else {
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 868cd65c7b17bbd45f96fd95d244517b685f9411..a2fdfd3ab1bdfd16379efb25548236fd742babcf 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -45,6 +45,8 @@ namespace internal {

 Heap::Heap()
     : isolate_(NULL),
+      amount_of_external_allocated_memory_(0),
+      amount_of_external_allocated_memory_at_last_global_gc_(0),
       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: src/heap.h
diff --git a/src/heap.h b/src/heap.h
index e9747df11403b9d1309facaf33545c1155d9d757..5ad67d67897639566fbd24b6e7bd905ad3eb48af 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -1504,6 +1504,13 @@ class Heap {
// more expedient to get at the isolate directly from within Heap methods.
   Isolate* isolate_;

+  // 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_;
+
   Object* roots_[kRootListLength];

   intptr_t code_range_size_;
@@ -1590,17 +1597,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: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index 7e60566ef66d9f82ccc19fb4efdd6677207a352f..cc968bbcc3b3dbfcb0410b367cbb1078b96b4f2e 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -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();


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to