* 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
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 {
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;
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;
}
+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) {
}
-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);
}
"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,
}
-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);
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.
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),
#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()),
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_ =
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);
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_;
// 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_;
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();
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(),
SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
- isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
+ reinterpret_cast<v8::Isolate*>(isolate)
+ ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
return true;
}