Skip to content

Commit

Permalink
Early out in ObjectPool to avoid loop execution (#1985)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomatosalat0 authored Oct 24, 2024
1 parent af0845f commit 6cb6d5d
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion Jint/Pooling/ObjectPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ private struct Element
// 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
Expand Down Expand Up @@ -158,13 +159,16 @@ internal T Allocate()

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;
}
Expand Down Expand Up @@ -202,13 +206,17 @@ internal void Free(T obj)
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))
{
// 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;
}
Expand Down

0 comments on commit 6cb6d5d

Please sign in to comment.