Index: include/v8.h |
diff --git a/include/v8.h b/include/v8.h |
index b1da55e2c5ee0d2cf566c976b95dde2e0396a27b..8984d92c75fc276bff432e35cd0570d7a40b3669 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 { |
@@ -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,13 +5565,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; |
@@ -6588,6 +6601,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) { |