Skip to content

Commit 40cb4da

Browse files
committed
Added the CollectGarbage method
1 parent a566a06 commit 40cb4da

File tree

11 files changed

+142
-1
lines changed

11 files changed

+142
-1
lines changed

src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,26 @@ internal abstract class ActiveScriptJsEngineBase : IInnerJsEngine, IActiveScript
3636
/// </summary>
3737
private IntPtr _pActiveScript;
3838

39+
/// <summary>
40+
/// Pointer to an instance of garbage collector
41+
/// </summary>
42+
private IntPtr _pActiveScriptGarbageCollector;
43+
3944
/// <summary>
4045
/// Instance of native JavaScript engine
4146
/// </summary>
4247
private IActiveScript _activeScript;
4348

4449
/// <summary>
45-
/// Instance of ActiveScriptParseWrapper
50+
/// Instance of <see cref="IActiveScriptParseWrapper"/>
4651
/// </summary>
4752
private IActiveScriptParseWrapper _activeScriptParse;
4853

54+
/// <summary>
55+
/// Instance of <see cref="IActiveScriptGarbageCollector"/>
56+
/// </summary>
57+
private IActiveScriptGarbageCollector _activeScriptGarbageCollector;
58+
4959
/// <summary>
5060
/// Instance of script dispatch
5161
/// </summary>
@@ -134,6 +144,9 @@ protected ActiveScriptJsEngineBase(string clsid, JsEngineMode engineMode, string
134144
_activeScriptParse = new ActiveScriptParseWrapper(_pActiveScript, _activeScript);
135145
_activeScriptParse.InitNew();
136146

147+
_pActiveScriptGarbageCollector = ComHelpers.QueryInterfaceNoThrow<IActiveScriptGarbageCollector>(_pActiveScript);
148+
_activeScriptGarbageCollector = _activeScript as IActiveScriptGarbageCollector;
149+
137150
_activeScript.SetScriptSite(this);
138151
_activeScript.SetScriptState(ScriptState.Started);
139152

@@ -481,6 +494,18 @@ private void EmbedHostItem(string itemName, object value)
481494
});
482495
}
483496

497+
/// <summary>
498+
/// Starts a garbage collection
499+
/// </summary>
500+
/// <param name="type">The type of garbage collection</param>
501+
private void InnerCollectGarbage(ScriptGCType type)
502+
{
503+
if (_activeScriptGarbageCollector != null)
504+
{
505+
_activeScriptGarbageCollector.CollectGarbage(type);
506+
}
507+
}
508+
484509
/// <summary>
485510
/// Loads a resources
486511
/// </summary>
@@ -541,6 +566,9 @@ private void Dispose(bool disposing)
541566
_dispatch = null;
542567
}
543568

569+
_activeScriptGarbageCollector = null;
570+
ComHelpers.ReleaseAndEmpty(ref _pActiveScriptGarbageCollector);
571+
544572
if (_activeScriptParse != null)
545573
{
546574
_activeScriptParse.Dispose();
@@ -550,6 +578,7 @@ private void Dispose(bool disposing)
550578
if (_activeScript != null)
551579
{
552580
_activeScript.Close();
581+
Marshal.FinalReleaseComObject(_activeScript);
553582
_activeScript = null;
554583
}
555584

@@ -796,6 +825,11 @@ public void EmbedHostType(string itemName, Type type)
796825
EmbedHostItem(itemName, typeValue);
797826
}
798827

828+
public void CollectGarbage()
829+
{
830+
InvokeScript(() => InnerCollectGarbage(ScriptGCType.Exhaustive));
831+
}
832+
799833
#endregion
800834

801835
#region IDisposable implementation
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#if !NETSTANDARD1_3
2+
using System.Runtime.InteropServices;
3+
4+
namespace MsieJavaScriptEngine.ActiveScript
5+
{
6+
/// <summary>
7+
/// Provides a method to start garbage collection.
8+
/// This interface should be implemented by Active Script engines that want to clean up their resources.
9+
/// </summary>
10+
[ComImport]
11+
[Guid("6aa2c4a0-2b53-11d4-a2a0-00104bd35090")]
12+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
13+
internal interface IActiveScriptGarbageCollector
14+
{
15+
/// <summary>
16+
/// Starts a garbage collection
17+
/// </summary>
18+
/// <param name="type">The type of garbage collection</param>
19+
void CollectGarbage([In] ScriptGCType type);
20+
}
21+
}
22+
#endif
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#if !NETSTANDARD1_3
2+
namespace MsieJavaScriptEngine.ActiveScript
3+
{
4+
/// <summary>
5+
/// The type of garbage collection
6+
/// </summary>
7+
internal enum ScriptGCType
8+
{
9+
/// <summary>
10+
/// Do normal garbage collection
11+
/// </summary>
12+
Normal = 0,
13+
14+
/// <summary>
15+
/// Do exhaustive garbage collection
16+
/// </summary>
17+
Exhaustive = 1
18+
}
19+
}
20+
#endif

src/MsieJavaScriptEngine/Helpers/ComHelpers.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ public static IntPtr QueryInterface<T>(IntPtr pUnknown)
6262
return pInterface;
6363
}
6464

65+
public static IntPtr QueryInterfaceNoThrow<T>(IntPtr pUnknown)
66+
{
67+
IntPtr pInterface;
68+
Guid iid = typeof(T).GetTypeInfo().GUID;
69+
int result = Marshal.QueryInterface(pUnknown, ref iid, out pInterface);
70+
71+
return result == HResult.S_OK ? pInterface : IntPtr.Zero;
72+
}
73+
6574
public static void ReleaseAndEmpty(ref IntPtr pUnk)
6675
{
6776
if (pUnk != IntPtr.Zero)
@@ -126,6 +135,9 @@ public static class HResult
126135
// ReSharper disable InconsistentNaming
127136
public const int SEVERITY_SUCCESS = 0;
128137
public const int SEVERITY_ERROR = 1;
138+
139+
public const int S_OK = 0;
140+
public const int S_FALSE = 1;
129141
// ReSharper restore InconsistentNaming
130142

131143
public static void Check(uint result)

src/MsieJavaScriptEngine/IInnerJsEngine.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,10 @@ internal interface IInnerJsEngine : IDisposable
7979
/// methods are bound to the type's static members.
8080
/// </remarks>
8181
void EmbedHostType(string itemName, Type type);
82+
83+
/// <summary>
84+
/// Performs a full garbage collection
85+
/// </summary>
86+
void CollectGarbage();
8287
}
8388
}

src/MsieJavaScriptEngine/JsRt/ChakraJsRtJsEngineBase.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ private void ExternalObjectFinalizeCallback(IntPtr data)
129129

130130
public abstract void EmbedHostType(string itemName, Type type);
131131

132+
public abstract void CollectGarbage();
133+
132134
#endregion
133135

134136
#region IDisposable implementation

src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,14 @@ public override void EmbedHostType(string itemName, Type type)
10371037
});
10381038
}
10391039

1040+
public override void CollectGarbage()
1041+
{
1042+
lock (_executionSynchronizer)
1043+
{
1044+
_jsRuntime.CollectGarbage();
1045+
}
1046+
}
1047+
10401048
#endregion
10411049

10421050
#region IDisposable implementation

src/MsieJavaScriptEngine/JsRt/Ie/ChakraIeJsRtJsEngine.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,14 @@ public override void EmbedHostType(string itemName, Type type)
10761076
});
10771077
}
10781078

1079+
public override void CollectGarbage()
1080+
{
1081+
lock (_executionSynchronizer)
1082+
{
1083+
_jsRuntime.CollectGarbage();
1084+
}
1085+
}
1086+
10791087
#endregion
10801088

10811089
#region IDisposable implementation

src/MsieJavaScriptEngine/MsieJavaScriptEngine.Net40.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
<Compile Include="ActiveScript\ActiveScriptParseWrapper.cs" />
5050
<Compile Include="ActiveScript\ChakraActiveScriptJsEngine.cs" />
5151
<Compile Include="ActiveScript\ClassicActiveScriptJsEngine.cs" />
52+
<Compile Include="ActiveScript\IActiveScriptGarbageCollector.cs" />
53+
<Compile Include="ActiveScript\ScriptGCType.cs" />
5254
<Compile Include="ActiveScript\ScriptHResult.cs" />
5355
<Compile Include="ActiveScript\IActiveScript.cs" />
5456
<Compile Include="ActiveScript\IActiveScriptError.cs" />

src/MsieJavaScriptEngine/MsieJsEngine.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,16 @@ public void EmbedHostType(string itemName, Type type)
733733
_jsEngine.EmbedHostType(itemName, type);
734734
}
735735

736+
/// <summary>
737+
/// Performs a full garbage collection
738+
/// </summary>
739+
public void CollectGarbage()
740+
{
741+
VerifyNotDisposed();
742+
743+
_jsEngine.CollectGarbage();
744+
}
745+
736746
#region IDisposable implementation
737747

738748
/// <summary>

0 commit comments

Comments
 (0)