[go: nahoru, domu]

Skip to content

Commit

Permalink
[vm, gc] Very basic RAIL.
Browse files Browse the repository at this point in the history
Related to #47574

TEST=ci
Change-Id: I2f07be6150b025a301e6e4d10935b606087cdf00
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252462
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
  • Loading branch information
rmacnak-google authored and Commit Bot committed Jul 27, 2022
1 parent 1c45840 commit c6a1eb1
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 7 deletions.
34 changes: 34 additions & 0 deletions runtime/include/dart_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,40 @@ DART_EXPORT void Dart_NotifyIdle(int64_t deadline);
*/
DART_EXPORT void Dart_NotifyLowMemory(void);

typedef enum {
/**
* Balanced
*/
Dart_PerformanceMode_Default,
/**
* Optimize for low latency, at the expense of throughput and memory overhead
* by performing work in smaller batches (requiring more overhead) or by
* delaying work (requiring more memory). An embedder should not remain in
* this mode indefinitely.
*/
Dart_PerformanceMode_Latency,
/**
* Optimize for high throughput, at the expense of latency and memory overhead
* by performing work in larger batches with more intervening growth.
*/
Dart_PerformanceMode_Throughput,
/**
* Optimize for low memory, at the expensive of throughput and latency by more
* frequently performing work.
*/
Dart_PerformanceMode_Memory,
} Dart_PerformanceMode;

/**
* Set the desired performance trade-off.
*
* Requires a current isolate.
*
* Returns the previous performance mode.
*/
DART_EXPORT Dart_PerformanceMode
Dart_SetPerformanceMode(Dart_PerformanceMode mode);

/**
* Starts the CPU sampling profiler.
*/
Expand Down
8 changes: 8 additions & 0 deletions runtime/vm/dart_api_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,14 @@ DART_EXPORT void Dart_NotifyLowMemory() {
// caches.
}

DART_EXPORT Dart_PerformanceMode
Dart_SetPerformanceMode(Dart_PerformanceMode mode) {
Thread* T = Thread::Current();
CHECK_ISOLATE(T->isolate());
TransitionNativeToVM transition(T);
return T->heap()->SetMode(mode);
}

DART_EXPORT void Dart_ExitIsolate() {
Thread* T = Thread::Current();
CHECK_ISOLATE(T->isolate());
Expand Down
44 changes: 44 additions & 0 deletions runtime/vm/dart_api_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9685,6 +9685,50 @@ void main() {
EXPECT_VALID(result);
}

static void SetPerformanceModeDefault(Dart_NativeArguments args) {
Dart_SetPerformanceMode(Dart_PerformanceMode_Default);
}
static void SetPerformanceModeLatency(Dart_NativeArguments args) {
Dart_SetPerformanceMode(Dart_PerformanceMode_Latency);
}

static Dart_NativeFunction SetMode_native_lookup(Dart_Handle name,
int argument_count,
bool* auto_setup_scope) {
const char* cstr = nullptr;
Dart_StringToCString(name, &cstr);
if (strcmp(cstr, "SetPerformanceModeDefault") == 0) {
return SetPerformanceModeDefault;
} else if (strcmp(cstr, "SetPerformanceModeLatency") == 0) {
return SetPerformanceModeLatency;
}
return NULL;
}

TEST_CASE(DartAPI_SetPerformanceMode) {
const char* kScriptChars = R"(
import "dart:typed_data";
@pragma("vm:external-name", "SetPerformanceModeDefault")
external void setPerformanceModeDefault();
@pragma("vm:external-name", "SetPerformanceModeLatency")
external void setPerformanceModeLatency();
void main() {
for (var i = 0; i < 10; i++) {
setPerformanceModeLatency();
var t = [];
for (var j = 0; j < 32; j++) {
t.add(Uint8List(1000000));
}
setPerformanceModeDefault();
}
}
)";
Dart_Handle lib =
TestCase::LoadTestScript(kScriptChars, &SetMode_native_lookup);
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
EXPECT_VALID(result);
}

static void NotifyLowMemoryNative(Dart_NativeArguments args) {
Dart_NotifyLowMemory();
}
Expand Down
25 changes: 25 additions & 0 deletions runtime/vm/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ void Heap::CheckExternalGC(Thread* thread) {
ASSERT(thread->no_safepoint_scope_depth() == 0);
ASSERT(thread->no_callback_scope_depth() == 0);
ASSERT(!thread->force_growth());

if (mode_ == Dart_PerformanceMode_Latency) {
return;
}

if (new_space_.ExternalInWords() >= (4 * new_space_.CapacityInWords())) {
// Attempt to free some external allocation by a scavenge. (If the total
// remains above the limit, next external alloc will trigger another.)
Expand Down Expand Up @@ -426,6 +431,15 @@ void Heap::NotifyIdle(int64_t deadline) {
}
}

Dart_PerformanceMode Heap::SetMode(Dart_PerformanceMode new_mode) {
Dart_PerformanceMode old_mode = mode_.exchange(new_mode);
if ((old_mode == Dart_PerformanceMode_Latency) &&
(new_mode == Dart_PerformanceMode_Default)) {
CheckCatchUp(Thread::Current());
}
return old_mode;
}

void Heap::CollectNewSpaceGarbage(Thread* thread,
GCType type,
GCReason reason) {
Expand Down Expand Up @@ -564,6 +578,15 @@ void Heap::CollectAllGarbage(GCReason reason, bool compact) {
WaitForSweeperTasks(thread);
}

void Heap::CheckCatchUp(Thread* thread) {
ASSERT(thread->CanCollectGarbage());
if (old_space()->ReachedHardThreshold()) {
CollectGarbage(thread, GCType::kMarkSweep, GCReason::kCatchUp);
} else {
CheckConcurrentMarking(thread, GCReason::kCatchUp, 0);
}
}

void Heap::CheckConcurrentMarking(Thread* thread,
GCReason reason,
intptr_t size) {
Expand Down Expand Up @@ -859,6 +882,8 @@ const char* Heap::GCReasonToString(GCReason gc_reason) {
return "idle";
case GCReason::kDebugging:
return "debugging";
case GCReason::kCatchUp:
return "catch-up";
default:
UNREACHABLE();
return "";
Expand Down
6 changes: 6 additions & 0 deletions runtime/vm/heap/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ class Heap {

void NotifyIdle(int64_t deadline);

Dart_PerformanceMode mode() const { return mode_; }
Dart_PerformanceMode SetMode(Dart_PerformanceMode mode);

// Collect a single generation.
void CollectGarbage(Thread* thread, GCType type, GCReason reason);

Expand All @@ -125,6 +128,7 @@ class Heap {
void CollectAllGarbage(GCReason reason = GCReason::kFull,
bool compact = false);

void CheckCatchUp(Thread* thread);
void CheckConcurrentMarking(Thread* thread, GCReason reason, intptr_t size);
void StartConcurrentMarking(Thread* thread, GCReason reason);
void WaitForMarkerTasks(Thread* thread);
Expand Down Expand Up @@ -362,6 +366,8 @@ class Heap {
// GC stats collection.
GCStats stats_;

RelaxedAtomic<Dart_PerformanceMode> mode_ = {Dart_PerformanceMode_Default};

// This heap is in read-only mode: No allocation is allowed.
bool read_only_;

Expand Down
6 changes: 6 additions & 0 deletions runtime/vm/heap/pages.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1524,13 +1524,19 @@ bool PageSpaceController::ReachedHardThreshold(SpaceUsage after) const {
if (heap_growth_ratio_ == 100) {
return false;
}
if ((heap_ != nullptr) && (heap_->mode() == Dart_PerformanceMode_Latency)) {
return false;
}
return after.CombinedUsedInWords() > hard_gc_threshold_in_words_;
}

bool PageSpaceController::ReachedSoftThreshold(SpaceUsage after) const {
if (heap_growth_ratio_ == 100) {
return false;
}
if ((heap_ != nullptr) && (heap_->mode() == Dart_PerformanceMode_Latency)) {
return false;
}
return after.CombinedUsedInWords() > soft_gc_threshold_in_words_;
}

Expand Down
8 changes: 1 addition & 7 deletions runtime/vm/heap/safepoint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,8 @@ ForceGrowthSafepointOperationScope::~ForceGrowthSafepointOperationScope() {

T->DecrementForceGrowthScopeDepth();
if (!T->force_growth()) {
ASSERT(T->CanCollectGarbage());
// Check if we passed the growth limit during the scope.
Heap* heap = T->heap();
if (heap->old_space()->ReachedHardThreshold()) {
heap->CollectGarbage(T, GCType::kMarkSweep, GCReason::kOldSpace);
} else {
heap->CheckConcurrentMarking(T, GCReason::kOldSpace, 0);
}
T->heap()->CheckCatchUp(T);
}
}

Expand Down
1 change: 1 addition & 0 deletions runtime/vm/heap/spaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ enum class GCReason {
kExternal, // Dart_NewFinalizableHandle Dart_NewWeakPersistentHandle
kIdle, // Dart_NotifyIdle
kDebugging, // service request, etc.
kCatchUp, // End of ForceGrowthScope or Dart_PerformanceMode_Latency.
};

} // namespace dart
Expand Down

0 comments on commit c6a1eb1

Please sign in to comment.