[heap] Internalize kExternalAllocationLimit
Base the fast-path in AdjustAmountOfExternalMemory on a value + limit. To preserve the behavior the limit is just set using kExternalAllocationLimit. Redo naming of related members. R=jochen@chromium.org BUG=chromium:621829 LOG=N Review-Url: https://codereview.chromium.org/2085893002 Cr-Commit-Position: refs/heads/master@{#37131}
This commit is contained in:
parent
f0dc0dbf21
commit
706b3f2730
38
include/v8.h
38
include/v8.h
@ -7493,13 +7493,12 @@ class Internals {
|
||||
static const int kExternalOneByteRepresentationTag = 0x06;
|
||||
|
||||
static const int kIsolateEmbedderDataOffset = 0 * kApiPointerSize;
|
||||
static const int kAmountOfExternalAllocatedMemoryOffset =
|
||||
4 * kApiPointerSize;
|
||||
static const int kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset =
|
||||
kAmountOfExternalAllocatedMemoryOffset + kApiInt64Size;
|
||||
static const int kIsolateRootsOffset =
|
||||
kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset + kApiInt64Size +
|
||||
kApiPointerSize + kApiPointerSize;
|
||||
static const int kExternalMemoryOffset = 4 * kApiPointerSize;
|
||||
static const int kExternalMemoryLimitOffset =
|
||||
kExternalMemoryOffset + kApiInt64Size;
|
||||
static const int kIsolateRootsOffset = kExternalMemoryLimitOffset +
|
||||
kApiInt64Size + kApiInt64Size +
|
||||
kApiPointerSize + kApiPointerSize;
|
||||
static const int kUndefinedValueRootIndex = 4;
|
||||
static const int kTheHoleValueRootIndex = 5;
|
||||
static const int kNullValueRootIndex = 6;
|
||||
@ -7507,10 +7506,6 @@ class Internals {
|
||||
static const int kFalseValueRootIndex = 8;
|
||||
static const int kEmptyStringRootIndex = 9;
|
||||
|
||||
// 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 = 0x7;
|
||||
@ -8705,21 +8700,16 @@ 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) {
|
||||
int64_t* external_memory = reinterpret_cast<int64_t*>(
|
||||
reinterpret_cast<uint8_t*>(this) + I::kExternalMemoryOffset);
|
||||
const int64_t external_memory_limit = *reinterpret_cast<int64_t*>(
|
||||
reinterpret_cast<uint8_t*>(this) + I::kExternalMemoryLimitOffset);
|
||||
const int64_t amount = *external_memory + change_in_bytes;
|
||||
*external_memory = amount;
|
||||
if (change_in_bytes > 0 && amount > external_memory_limit) {
|
||||
ReportExternalAllocationLimitReached();
|
||||
}
|
||||
*amount_of_external_allocated_memory = amount;
|
||||
return *amount_of_external_allocated_memory;
|
||||
return *external_memory;
|
||||
}
|
||||
|
||||
|
||||
|
@ -135,8 +135,7 @@ void StatisticsExtension::GetCounters(
|
||||
AddNumber(args.GetIsolate(), result, numbers[i].number, numbers[i].name);
|
||||
}
|
||||
|
||||
AddNumber64(args.GetIsolate(), result,
|
||||
heap->amount_of_external_allocated_memory(),
|
||||
AddNumber64(args.GetIsolate(), result, heap->external_memory(),
|
||||
"amount_of_external_allocated_memory");
|
||||
args.GetReturnValue().Set(result);
|
||||
}
|
||||
|
@ -182,6 +182,10 @@ const size_t kCodeRangeAreaAlignment = 4 * KB; // OS page.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// The external allocation limit should be below 256 MB on all architectures
|
||||
// to avoid that resource-constrained embedders run low on memory.
|
||||
const int kExternalAllocationLimit = 192 * 1024 * 1024;
|
||||
|
||||
STATIC_ASSERT(kPointerSize == (1 << kPointerSizeLog2));
|
||||
|
||||
const int kBitsPerByte = 8;
|
||||
|
@ -44,8 +44,7 @@ void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer* buffer) {
|
||||
DCHECK_NOT_NULL(tracker);
|
||||
length = tracker->Remove(buffer).second;
|
||||
}
|
||||
heap->update_amount_of_external_allocated_memory(
|
||||
-static_cast<intptr_t>(length));
|
||||
heap->update_external_memory(-static_cast<intptr_t>(length));
|
||||
}
|
||||
|
||||
void LocalArrayBufferTracker::Add(Key key, const Value& value) {
|
||||
|
@ -29,7 +29,7 @@ void LocalArrayBufferTracker::Free() {
|
||||
}
|
||||
}
|
||||
if (freed_memory > 0) {
|
||||
heap_->update_amount_of_external_allocated_freed_memory(
|
||||
heap_->update_external_memory_concurrently_freed(
|
||||
static_cast<intptr_t>(freed_memory));
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,7 @@ void LocalArrayBufferTracker::Process(Callback callback) {
|
||||
}
|
||||
}
|
||||
if (freed_memory > 0) {
|
||||
heap_->update_amount_of_external_allocated_freed_memory(
|
||||
heap_->update_external_memory_concurrently_freed(
|
||||
static_cast<intptr_t>(freed_memory));
|
||||
}
|
||||
}
|
||||
@ -82,7 +82,7 @@ void ArrayBufferTracker::FreeDeadInNewSpace(Heap* heap) {
|
||||
bool empty = ProcessBuffers(page, kUpdateForwardedRemoveOthers);
|
||||
CHECK(empty);
|
||||
}
|
||||
heap->account_amount_of_external_allocated_freed_memory();
|
||||
heap->account_external_memory_concurrently_freed();
|
||||
}
|
||||
|
||||
void ArrayBufferTracker::FreeDead(Page* page) {
|
||||
|
@ -68,8 +68,9 @@ class IdleScavengeObserver : public AllocationObserver {
|
||||
};
|
||||
|
||||
Heap::Heap()
|
||||
: amount_of_external_allocated_memory_(0),
|
||||
amount_of_external_allocated_memory_at_last_global_gc_(0),
|
||||
: external_memory_(0),
|
||||
external_memory_limit_(kExternalAllocationLimit),
|
||||
external_memory_at_last_mark_compact_(0),
|
||||
isolate_(nullptr),
|
||||
code_range_size_(0),
|
||||
// semispace_size_ should be a power of 2 and old_generation_size_ should
|
||||
@ -383,9 +384,8 @@ void Heap::PrintShortHeapStatistics() {
|
||||
", committed: %6" V8PRIdPTR " KB\n",
|
||||
this->SizeOfObjects() / KB, this->Available() / KB,
|
||||
this->CommittedMemory() / KB);
|
||||
PrintIsolate(
|
||||
isolate_, "External memory reported: %6" V8PRIdPTR " KB\n",
|
||||
static_cast<intptr_t>(amount_of_external_allocated_memory_ / KB));
|
||||
PrintIsolate(isolate_, "External memory reported: %6" V8PRIdPTR " KB\n",
|
||||
static_cast<intptr_t>(external_memory_ / KB));
|
||||
PrintIsolate(isolate_, "Total time spent in GC : %.1f ms\n",
|
||||
total_gc_time_ms_);
|
||||
}
|
||||
@ -1339,8 +1339,8 @@ bool Heap::PerformGarbageCollection(
|
||||
intptr_t old_gen_size = PromotedSpaceSizeOfObjects();
|
||||
if (collector == MARK_COMPACTOR) {
|
||||
// Register the amount of external allocated memory.
|
||||
amount_of_external_allocated_memory_at_last_global_gc_ =
|
||||
amount_of_external_allocated_memory_;
|
||||
external_memory_at_last_mark_compact_ = external_memory_;
|
||||
external_memory_limit_ = external_memory_ + kExternalAllocationLimit;
|
||||
SetOldGenerationAllocationLimit(old_gen_size, gc_speed, mutator_speed);
|
||||
} else if (HasLowYoungGenerationAllocationRate() &&
|
||||
old_generation_size_configured_) {
|
||||
@ -4425,8 +4425,8 @@ void Heap::CollectGarbageOnMemoryPressure(const char* source) {
|
||||
double end = MonotonicallyIncreasingTimeInMs();
|
||||
|
||||
// Estimate how much memory we can free.
|
||||
int64_t potential_garbage = (CommittedMemory() - SizeOfObjects()) +
|
||||
amount_of_external_allocated_memory_;
|
||||
int64_t potential_garbage =
|
||||
(CommittedMemory() - SizeOfObjects()) + external_memory_;
|
||||
// If we can potentially free large amount of memory, then start GC right
|
||||
// away instead of waiting for memory reducer.
|
||||
if (potential_garbage >= kGarbageThresholdInBytes &&
|
||||
@ -5048,11 +5048,8 @@ intptr_t Heap::PromotedSpaceSizeOfObjects() {
|
||||
|
||||
|
||||
int64_t Heap::PromotedExternalMemorySize() {
|
||||
if (amount_of_external_allocated_memory_ <=
|
||||
amount_of_external_allocated_memory_at_last_global_gc_)
|
||||
return 0;
|
||||
return amount_of_external_allocated_memory_ -
|
||||
amount_of_external_allocated_memory_at_last_global_gc_;
|
||||
if (external_memory_ <= external_memory_at_last_mark_compact_) return 0;
|
||||
return external_memory_ - external_memory_at_last_mark_compact_;
|
||||
}
|
||||
|
||||
|
||||
|
@ -821,22 +821,16 @@ class Heap {
|
||||
global_ic_age_ = (global_ic_age_ + 1) & SharedFunctionInfo::ICAgeBits::kMax;
|
||||
}
|
||||
|
||||
int64_t amount_of_external_allocated_memory() {
|
||||
return amount_of_external_allocated_memory_;
|
||||
int64_t external_memory() { return external_memory_; }
|
||||
void update_external_memory(int64_t delta) { external_memory_ += delta; }
|
||||
|
||||
void update_external_memory_concurrently_freed(intptr_t freed) {
|
||||
external_memory_concurrently_freed_.Increment(freed);
|
||||
}
|
||||
|
||||
void update_amount_of_external_allocated_memory(int64_t delta) {
|
||||
amount_of_external_allocated_memory_ += delta;
|
||||
}
|
||||
|
||||
void update_amount_of_external_allocated_freed_memory(intptr_t freed) {
|
||||
amount_of_external_allocated_memory_freed_.Increment(freed);
|
||||
}
|
||||
|
||||
void account_amount_of_external_allocated_freed_memory() {
|
||||
amount_of_external_allocated_memory_ -=
|
||||
amount_of_external_allocated_memory_freed_.Value();
|
||||
amount_of_external_allocated_memory_freed_.SetValue(0);
|
||||
void account_external_memory_concurrently_freed() {
|
||||
external_memory_ -= external_memory_concurrently_freed_.Value();
|
||||
external_memory_concurrently_freed_.SetValue(0);
|
||||
}
|
||||
|
||||
void DeoptMarkedAllocationSites();
|
||||
@ -1997,14 +1991,17 @@ class Heap {
|
||||
|
||||
void set_force_oom(bool value) { force_oom_ = value; }
|
||||
|
||||
// The amount of external memory registered through the API kept alive
|
||||
// by global handles
|
||||
int64_t amount_of_external_allocated_memory_;
|
||||
// The amount of external memory registered through the API.
|
||||
int64_t external_memory_;
|
||||
|
||||
// Caches the amount of external memory registered at the last global gc.
|
||||
int64_t amount_of_external_allocated_memory_at_last_global_gc_;
|
||||
// The limit when to trigger memory pressure from the API.
|
||||
int64_t external_memory_limit_;
|
||||
|
||||
base::AtomicNumber<intptr_t> amount_of_external_allocated_memory_freed_;
|
||||
// Caches the amount of external memory registered at the last MC.
|
||||
int64_t external_memory_at_last_mark_compact_;
|
||||
|
||||
// The amount of memory that has been freed concurrently.
|
||||
base::AtomicNumber<intptr_t> external_memory_concurrently_freed_;
|
||||
|
||||
// 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.
|
||||
|
@ -898,7 +898,7 @@ void MarkCompactCollector::Prepare() {
|
||||
space = spaces.next()) {
|
||||
space->PrepareForMarkCompact();
|
||||
}
|
||||
heap()->account_amount_of_external_allocated_freed_memory();
|
||||
heap()->account_external_memory_concurrently_freed();
|
||||
|
||||
#ifdef VERIFY_HEAP
|
||||
if (!was_marked_incrementally_ && FLAG_verify_heap) {
|
||||
|
@ -2312,13 +2312,10 @@ 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);
|
||||
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.external_memory_)),
|
||||
Internals::kExternalMemoryOffset);
|
||||
CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.external_memory_limit_)),
|
||||
Internals::kExternalMemoryLimitOffset);
|
||||
|
||||
time_millis_at_init_ = heap_.MonotonicallyIncreasingTimeInMs();
|
||||
|
||||
|
@ -6717,7 +6717,7 @@ TEST(Regress618958) {
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Heap* heap = CcTest::heap();
|
||||
bool isolate_is_locked = true;
|
||||
heap->update_amount_of_external_allocated_memory(100 * MB);
|
||||
heap->update_external_memory(100 * MB);
|
||||
int mark_sweep_count_before = heap->ms_count();
|
||||
heap->MemoryPressureNotification(MemoryPressureLevel::kCritical,
|
||||
isolate_is_locked);
|
||||
|
@ -14853,8 +14853,7 @@ THREADED_TEST(ExternalAllocatedMemory) {
|
||||
isolate->AdjustAmountOfExternalAllocatedMemory(kSize));
|
||||
CHECK_EQ(baseline,
|
||||
isolate->AdjustAmountOfExternalAllocatedMemory(-kSize));
|
||||
const int64_t kTriggerGCSize =
|
||||
v8::internal::Internals::kExternalAllocationLimit + 1;
|
||||
const int64_t kTriggerGCSize = i::kExternalAllocationLimit + 1;
|
||||
CHECK_EQ(baseline + kTriggerGCSize,
|
||||
isolate->AdjustAmountOfExternalAllocatedMemory(kTriggerGCSize));
|
||||
CHECK_EQ(baseline,
|
||||
@ -14866,8 +14865,7 @@ TEST(Regress51719) {
|
||||
i::FLAG_incremental_marking = false;
|
||||
CcTest::InitializeVM();
|
||||
|
||||
const int64_t kTriggerGCSize =
|
||||
v8::internal::Internals::kExternalAllocationLimit + 1;
|
||||
const int64_t kTriggerGCSize = i::kExternalAllocationLimit + 1;
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
isolate->AdjustAmountOfExternalAllocatedMemory(kTriggerGCSize);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user