@@ -412,6 +412,13 @@ class Fiber {
412
412
static vector<Fiber*> orphaned_fibers;
413
413
static Persistent<Value> fatal_stack;
414
414
415
+ static size_t external_bytes_used;
416
+ static size_t external_bytes_reported;
417
+ // We report external memory usage only when the difference
418
+ // between used and reported exceeds threshold, to avoid calling
419
+ // uni::AdjustAmountOfExternalAllocatedMemory too often.
420
+ static int external_bytes_threshold;
421
+
415
422
Isolate* isolate;
416
423
Persistent<Object> handle;
417
424
Persistent<Function> cb;
@@ -578,7 +585,7 @@ class Fiber {
578
585
THROW (Exception::RangeError, " Out of memory" );
579
586
}
580
587
that.started = true ;
581
- uni::AdjustAmountOfExternalAllocatedMemory (that. isolate , that. this_fiber -> size () * GC_ADJUST );
588
+ AdjustExternalMemoryOnFiberStart (that);
582
589
} else {
583
590
// If the fiber is currently running put the first parameter to `run()` on `yielded`, then
584
591
// the pending call to `yield()` will return that value. `yielded` in this case is just a
@@ -760,7 +767,7 @@ class Fiber {
760
767
761
768
// Do not invoke the garbage collector if there's no context on the stack. It will seg fault
762
769
// otherwise.
763
- uni::AdjustAmountOfExternalAllocatedMemory (that. isolate , -( int )(that. this_fiber -> size () * GC_ADJUST) );
770
+ AdjustExternalMemoryOnFiberExit (that);
764
771
765
772
// Don't make weak until after notifying the garbage collector. Otherwise it may try and
766
773
// free this very fiber!
@@ -859,6 +866,24 @@ class Fiber {
859
866
return uni::Return (uni::NewNumber (Isolate::GetCurrent (), Coroutine::coroutines_created ()), info);
860
867
}
861
868
869
+ static void AdjustExternalMemoryOnFiberStart (const Fiber& fiber) {
870
+ external_bytes_used += fiber.this_fiber ->size () * GC_ADJUST;
871
+ int diff = external_bytes_used - external_bytes_reported;
872
+ if (diff > external_bytes_threshold) {
873
+ uni::AdjustAmountOfExternalAllocatedMemory (fiber.isolate , diff);
874
+ external_bytes_reported = external_bytes_used;
875
+ }
876
+ }
877
+
878
+ static void AdjustExternalMemoryOnFiberExit (const Fiber& fiber) {
879
+ external_bytes_used -= fiber.this_fiber ->size () * GC_ADJUST;
880
+ int diff = external_bytes_used - external_bytes_reported;
881
+ if (-diff > external_bytes_threshold) {
882
+ uni::AdjustAmountOfExternalAllocatedMemory (fiber.isolate , diff);
883
+ external_bytes_reported = external_bytes_used;
884
+ }
885
+ }
886
+
862
887
public:
863
888
/* *
864
889
* Initialize the Fiber library.
@@ -918,6 +943,14 @@ Locker* Fiber::global_locker;
918
943
Fiber* Fiber::current = NULL ;
919
944
vector<Fiber*> Fiber::orphaned_fibers;
920
945
Persistent<Value> Fiber::fatal_stack;
946
+
947
+ // Used by AdjustExternalMemoryOnFiber{Start,Exit} to avoid calling
948
+ // uni::AdjustAmountOfExternalAllocatedMemory every time a Fiber starts
949
+ // or exits.
950
+ size_t Fiber::external_bytes_used = 0 ;
951
+ size_t Fiber::external_bytes_reported = 0 ;
952
+ int Fiber::external_bytes_threshold = 1024 * 1024 ;
953
+
921
954
bool did_init = false ;
922
955
923
956
#if !NODE_VERSION_AT_LEAST(0,10,0)
0 commit comments