Unify memory optimization modes and flags.
This patch folds --optimize-for-size flag and check for low-memory device into Heap::ShouldOptimizeForMemoryUsage() predicate. It has the following side effects: - the heap growing factor for low-memory devices is capped at 1.3 (old value was 2.0). - the memory reducer will be more aggressive for low-memory devices. BUG=chromium:634900 Review-Url: https://codereview.chromium.org/2218703004 Cr-Commit-Position: refs/heads/master@{#38406}
This commit is contained in:
parent
422d14350d
commit
6cebf7d963
@ -7858,13 +7858,13 @@ int Isolate::ContextDisposedNotification(bool dependant_context) {
|
|||||||
|
|
||||||
void Isolate::IsolateInForegroundNotification() {
|
void Isolate::IsolateInForegroundNotification() {
|
||||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||||
return isolate->heap()->SetOptimizeForLatency();
|
return isolate->IsolateInForegroundNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Isolate::IsolateInBackgroundNotification() {
|
void Isolate::IsolateInBackgroundNotification() {
|
||||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||||
return isolate->heap()->SetOptimizeForMemoryUsage();
|
return isolate->IsolateInBackgroundNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
|
void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
|
||||||
|
@ -112,7 +112,6 @@ Heap::Heap()
|
|||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
old_generation_allocation_limit_(initial_old_generation_size_),
|
old_generation_allocation_limit_(initial_old_generation_size_),
|
||||||
old_gen_exhausted_(false),
|
old_gen_exhausted_(false),
|
||||||
optimize_for_memory_usage_(false),
|
|
||||||
inline_allocation_disabled_(false),
|
inline_allocation_disabled_(false),
|
||||||
total_regexp_code_generated_(0),
|
total_regexp_code_generated_(0),
|
||||||
tracer_(nullptr),
|
tracer_(nullptr),
|
||||||
@ -4109,19 +4108,24 @@ bool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) {
|
|||||||
return committed - used > used + kSlack;
|
return committed - used > used + kSlack;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heap::SetOptimizeForMemoryUsage() {
|
bool Heap::ShouldOptimizeForMemoryUsage() {
|
||||||
|
return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() ||
|
||||||
|
HighMemoryPressure() || IsLowMemoryDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Heap::ActivateMemoryReducerIfNeeded() {
|
||||||
// Activate memory reducer when switching to background if
|
// Activate memory reducer when switching to background if
|
||||||
// - there was no mark compact since the start.
|
// - there was no mark compact since the start.
|
||||||
// - the committed memory can be potentially reduced.
|
// - the committed memory can be potentially reduced.
|
||||||
// 2 pages for the old, code, and map space + 1 page for new space.
|
// 2 pages for the old, code, and map space + 1 page for new space.
|
||||||
const int kMinCommittedMemory = 7 * Page::kPageSize;
|
const int kMinCommittedMemory = 7 * Page::kPageSize;
|
||||||
if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory) {
|
if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory &&
|
||||||
|
isolate()->IsIsolateInBackground()) {
|
||||||
MemoryReducer::Event event;
|
MemoryReducer::Event event;
|
||||||
event.type = MemoryReducer::kPossibleGarbage;
|
event.type = MemoryReducer::kPossibleGarbage;
|
||||||
event.time_ms = MonotonicallyIncreasingTimeInMs();
|
event.time_ms = MonotonicallyIncreasingTimeInMs();
|
||||||
memory_reducer_->NotifyPossibleGarbage(event);
|
memory_reducer_->NotifyPossibleGarbage(event);
|
||||||
}
|
}
|
||||||
optimize_for_memory_usage_ = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heap::ReduceNewSpaceSize() {
|
void Heap::ReduceNewSpaceSize() {
|
||||||
@ -5081,6 +5085,7 @@ const double Heap::kMinHeapGrowingFactor = 1.1;
|
|||||||
const double Heap::kMaxHeapGrowingFactor = 4.0;
|
const double Heap::kMaxHeapGrowingFactor = 4.0;
|
||||||
const double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0;
|
const double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0;
|
||||||
const double Heap::kMaxHeapGrowingFactorIdle = 1.5;
|
const double Heap::kMaxHeapGrowingFactorIdle = 1.5;
|
||||||
|
const double Heap::kConservativeHeapGrowingFactor = 1.3;
|
||||||
const double Heap::kTargetMutatorUtilization = 0.97;
|
const double Heap::kTargetMutatorUtilization = 0.97;
|
||||||
|
|
||||||
|
|
||||||
@ -5156,8 +5161,6 @@ intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor,
|
|||||||
void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
|
void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
|
||||||
double gc_speed,
|
double gc_speed,
|
||||||
double mutator_speed) {
|
double mutator_speed) {
|
||||||
const double kConservativeHeapGrowingFactor = 1.3;
|
|
||||||
|
|
||||||
double factor = HeapGrowingFactor(gc_speed, mutator_speed);
|
double factor = HeapGrowingFactor(gc_speed, mutator_speed);
|
||||||
|
|
||||||
if (FLAG_trace_gc_verbose) {
|
if (FLAG_trace_gc_verbose) {
|
||||||
@ -5168,14 +5171,12 @@ void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
|
|||||||
gc_speed, mutator_speed);
|
gc_speed, mutator_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We set the old generation growing factor to 2 to grow the heap slower on
|
if (IsMemoryConstrainedDevice()) {
|
||||||
// memory-constrained devices.
|
|
||||||
if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice ||
|
|
||||||
FLAG_optimize_for_size) {
|
|
||||||
factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained);
|
factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memory_reducer_->ShouldGrowHeapSlowly() || optimize_for_memory_usage_) {
|
if (memory_reducer_->ShouldGrowHeapSlowly() ||
|
||||||
|
ShouldOptimizeForMemoryUsage()) {
|
||||||
factor = Min(factor, kConservativeHeapGrowingFactor);
|
factor = Min(factor, kConservativeHeapGrowingFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +563,7 @@ class Heap {
|
|||||||
static const double kMaxHeapGrowingFactor;
|
static const double kMaxHeapGrowingFactor;
|
||||||
static const double kMaxHeapGrowingFactorMemoryConstrained;
|
static const double kMaxHeapGrowingFactorMemoryConstrained;
|
||||||
static const double kMaxHeapGrowingFactorIdle;
|
static const double kMaxHeapGrowingFactorIdle;
|
||||||
|
static const double kConservativeHeapGrowingFactor;
|
||||||
static const double kTargetMutatorUtilization;
|
static const double kTargetMutatorUtilization;
|
||||||
|
|
||||||
static const int kNoGCFlags = 0;
|
static const int kNoGCFlags = 0;
|
||||||
@ -888,11 +889,18 @@ class Heap {
|
|||||||
bool HasHighFragmentation();
|
bool HasHighFragmentation();
|
||||||
bool HasHighFragmentation(intptr_t used, intptr_t committed);
|
bool HasHighFragmentation(intptr_t used, intptr_t committed);
|
||||||
|
|
||||||
void SetOptimizeForLatency() { optimize_for_memory_usage_ = false; }
|
void ActivateMemoryReducerIfNeeded();
|
||||||
void SetOptimizeForMemoryUsage();
|
|
||||||
bool ShouldOptimizeForMemoryUsage() {
|
bool ShouldOptimizeForMemoryUsage();
|
||||||
return optimize_for_memory_usage_ || HighMemoryPressure();
|
|
||||||
|
bool IsLowMemoryDevice() {
|
||||||
|
return max_old_generation_size_ <= kMaxOldSpaceSizeLowMemoryDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsMemoryConstrainedDevice() {
|
||||||
|
return max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice;
|
||||||
|
}
|
||||||
|
|
||||||
bool HighMemoryPressure() {
|
bool HighMemoryPressure() {
|
||||||
return memory_pressure_level_.Value() != MemoryPressureLevel::kNone;
|
return memory_pressure_level_.Value() != MemoryPressureLevel::kNone;
|
||||||
}
|
}
|
||||||
@ -2119,10 +2127,6 @@ class Heap {
|
|||||||
// last GC.
|
// last GC.
|
||||||
bool old_gen_exhausted_;
|
bool old_gen_exhausted_;
|
||||||
|
|
||||||
// Indicates that memory usage is more important than latency.
|
|
||||||
// TODO(ulan): Merge it with memory reducer once chromium:490559 is fixed.
|
|
||||||
bool optimize_for_memory_usage_;
|
|
||||||
|
|
||||||
// Indicates that inline bump-pointer allocation has been globally disabled
|
// Indicates that inline bump-pointer allocation has been globally disabled
|
||||||
// for all spaces. This is used to disable allocations in generated code.
|
// for all spaces. This is used to disable allocations in generated code.
|
||||||
bool inline_allocation_disabled_;
|
bool inline_allocation_disabled_;
|
||||||
|
@ -1998,6 +1998,7 @@ Isolate::Isolate(bool enable_serializer)
|
|||||||
has_fatal_error_(false),
|
has_fatal_error_(false),
|
||||||
initialized_from_snapshot_(false),
|
initialized_from_snapshot_(false),
|
||||||
is_tail_call_elimination_enabled_(true),
|
is_tail_call_elimination_enabled_(true),
|
||||||
|
is_isolate_in_background_(false),
|
||||||
cpu_profiler_(NULL),
|
cpu_profiler_(NULL),
|
||||||
heap_profiler_(NULL),
|
heap_profiler_(NULL),
|
||||||
code_event_dispatcher_(new CodeEventDispatcher()),
|
code_event_dispatcher_(new CodeEventDispatcher()),
|
||||||
@ -3172,6 +3173,15 @@ void Isolate::SetRAILMode(RAILMode rail_mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Isolate::IsolateInBackgroundNotification() {
|
||||||
|
is_isolate_in_background_ = false;
|
||||||
|
heap()->ActivateMemoryReducerIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Isolate::IsolateInForegroundNotification() {
|
||||||
|
is_isolate_in_background_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool StackLimitCheck::JsHasOverflowed(uintptr_t gap) const {
|
bool StackLimitCheck::JsHasOverflowed(uintptr_t gap) const {
|
||||||
StackGuard* stack_guard = isolate_->stack_guard();
|
StackGuard* stack_guard = isolate_->stack_guard();
|
||||||
#ifdef USE_SIMULATOR
|
#ifdef USE_SIMULATOR
|
||||||
|
@ -1162,6 +1162,12 @@ class Isolate {
|
|||||||
|
|
||||||
void SetRAILMode(RAILMode rail_mode);
|
void SetRAILMode(RAILMode rail_mode);
|
||||||
|
|
||||||
|
void IsolateInForegroundNotification();
|
||||||
|
|
||||||
|
void IsolateInBackgroundNotification();
|
||||||
|
|
||||||
|
bool IsIsolateInBackground() { return is_isolate_in_background_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Isolate(bool enable_serializer);
|
explicit Isolate(bool enable_serializer);
|
||||||
bool IsArrayOrObjectPrototype(Object* object);
|
bool IsArrayOrObjectPrototype(Object* object);
|
||||||
@ -1353,6 +1359,10 @@ class Isolate {
|
|||||||
// True if ES2015 tail call elimination feature is enabled.
|
// True if ES2015 tail call elimination feature is enabled.
|
||||||
bool is_tail_call_elimination_enabled_;
|
bool is_tail_call_elimination_enabled_;
|
||||||
|
|
||||||
|
// True if the isolate is in background. This flag is used
|
||||||
|
// to prioritize between memory usage and latency.
|
||||||
|
bool is_isolate_in_background_;
|
||||||
|
|
||||||
// Time stamp at initialization.
|
// Time stamp at initialization.
|
||||||
double time_millis_at_init_;
|
double time_millis_at_init_;
|
||||||
|
|
||||||
|
@ -25348,6 +25348,7 @@ class MemoryPressureThread : public v8::base::Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST(MemoryPressure) {
|
TEST(MemoryPressure) {
|
||||||
|
if (v8::internal::FLAG_optimize_for_size) return;
|
||||||
v8::Isolate* isolate = CcTest::isolate();
|
v8::Isolate* isolate = CcTest::isolate();
|
||||||
WeakCallCounter counter(1234);
|
WeakCallCounter counter(1234);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user