Browse Source

Early out in ObjectPool to avoid loop execution (#1985)

tomatosalat0 9 tháng trước cách đây
mục cha
commit
6cb6d5dd8d
1 tập tin đã thay đổi với 9 bổ sung1 xóa
  1. 9 1
      Jint/Pooling/ObjectPool.cs

+ 9 - 1
Jint/Pooling/ObjectPool.cs

@@ -57,6 +57,7 @@ internal sealed class ObjectPool<T> where T : class
     // expect to be able to satisfy most requests from it.
     private T _firstItem;
     private readonly Element[] _items;
+    private int _currentSlowPooledItems;
 
     // factory is stored for the lifetime of the pool. We will call this only when pool needs to
     // expand. compared to "new T()", Func gives more flexibility to implementers and faster
@@ -158,13 +159,16 @@ internal sealed class ObjectPool<T> where T : class
 
     private T AllocateSlow()
     {
-        var items = _items;
+        if (_currentSlowPooledItems <= 0)
+            return CreateInstance();
 
+        var items = _items;
         for (int i = 0; i < items.Length; i++)
         {
             T inst = items[i].Value;
             if (inst is not null)
             {
+                _currentSlowPooledItems--;
                 items[i].Value = null;
                 return inst;
             }
@@ -202,6 +206,9 @@ internal sealed class ObjectPool<T> where T : class
     private void FreeSlow(T obj)
     {
         var items = _items;
+        if (_currentSlowPooledItems >= items.Length)
+            return;
+
         for (int i = 0; i < items.Length; i++)
         {
             if (ReferenceEquals(items[i].Value, null))
@@ -209,6 +216,7 @@ internal sealed class ObjectPool<T> where T : class
                 // Intentionally not using interlocked here.
                 // In a worst case scenario two objects may be stored into same slot.
                 // It is very unlikely to happen and will only mean that one of the objects will get collected.
+                _currentSlowPooledItems++;
                 items[i].Value = obj;
                 break;
             }