@@ -297,8 +297,11 @@ public virtual string GetInitJavaScript()
297297 }
298298
299299 /// <summary>
300- /// Attempts to execute the provided JavaScript code using the current engine. If an
301- /// exception is thrown, retries the execution using a new thread (and hence a new engine)
300+ /// Attempts to execute the provided JavaScript code using a non-pooled JavaScript engine (ie.
301+ /// creates a new JS engine per-thread). This is because Babel uses a LOT of memory, so we
302+ /// should completely dispose any engines that have loaded Babel in order to conserve memory.
303+ ///
304+ /// If an exception is thrown, retries the execution using a new thread (and hence a new engine)
302305 /// with a larger maximum stack size.
303306 /// This is required because JSXTransformer uses a huge stack which ends up being larger
304307 /// than what ASP.NET allows by default (256 KB).
@@ -307,18 +310,14 @@ public virtual string GetInitJavaScript()
307310 /// <param name="function">JavaScript function to execute</param>
308311 /// <param name="args">Arguments to pass to function</param>
309312 /// <returns>Result returned from JavaScript code</returns>
310- public virtual T ExecuteWithLargerStackIfRequired < T > ( string function , params object [ ] args )
313+ public virtual T ExecuteWithBabel < T > ( string function , params object [ ] args )
311314 {
312- // This hack is not required when pooling JavaScript engines, since pooled MSIE
313- // engines already execute on their own thread with a larger stack.
314- if ( _config . ReuseJavaScriptEngines )
315- {
316- return Execute < T > ( function , args ) ;
317- }
315+ var engine = _engineFactory . GetEngineForCurrentThread ( ) ;
316+ EnsureBabelLoaded ( engine ) ;
318317
319318 try
320319 {
321- return Execute < T > ( function , args ) ;
320+ return engine . CallFunctionReturningJson < T > ( function , args ) ;
322321 }
323322 catch ( Exception )
324323 {
@@ -330,10 +329,11 @@ public virtual T ExecuteWithLargerStackIfRequired<T>(string function, params obj
330329 var thread = new Thread ( ( ) =>
331330 {
332331 // New engine will be created here (as this is a new thread)
333- var engine = _engineFactory . GetEngineForCurrentThread ( ) ;
332+ var threadEngine = _engineFactory . GetEngineForCurrentThread ( ) ;
333+ EnsureBabelLoaded ( threadEngine ) ;
334334 try
335335 {
336- result = engine . CallFunctionReturningJson < T > ( function , args ) ;
336+ result = threadEngine . CallFunctionReturningJson < T > ( function , args ) ;
337337 }
338338 catch ( Exception threadEx )
339339 {
@@ -417,18 +417,18 @@ public virtual IReactSiteConfiguration Configuration
417417 /// <summary>
418418 /// Ensures that Babel has been loaded into the JavaScript engine.
419419 /// </summary>
420- public void EnsureBabelLoaded ( )
420+ private void EnsureBabelLoaded ( IJsEngine engine )
421421 {
422422 // If Babel is disabled in the config, don't even try loading it
423423 if ( ! _config . LoadBabel )
424424 {
425425 throw new BabelNotLoadedException ( ) ;
426426 }
427427
428- var babelLoaded = Engine . Evaluate < bool > ( "typeof global.Babel !== 'undefined'" ) ;
428+ var babelLoaded = engine . Evaluate < bool > ( "typeof global.Babel !== 'undefined'" ) ;
429429 if ( ! babelLoaded )
430430 {
431- Engine . ExecuteResource ( "React.node_modules.babel_core.browser.js" , typeof ( ReactEnvironment ) . Assembly ) ;
431+ engine . ExecuteResource ( "React.node_modules.babel_core.browser.js" , typeof ( ReactEnvironment ) . Assembly ) ;
432432 }
433433 }
434434 }
0 commit comments