Title: [92386] trunk/Source/_javascript_Core
Revision
92386
Author
[email protected]
Date
2011-08-04 10:48:40 -0700 (Thu, 04 Aug 2011)

Log Message

Eval handling attempts literal parsing even when the eval
string is in the cache
https://bugs.webkit.org/show_bug.cgi?id=65675

Reviewed by Oliver Hunt.

This is a 25% speed-up on date-format-tofte and a 1.5% speed-up overall
in SunSpider.  It's neutral on V8.

* bytecode/EvalCodeCache.h:
(JSC::EvalCodeCache::tryGet):
(JSC::EvalCodeCache::getSlow):
(JSC::EvalCodeCache::get):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::callEval):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (92385 => 92386)


--- trunk/Source/_javascript_Core/ChangeLog	2011-08-04 17:48:06 UTC (rev 92385)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-08-04 17:48:40 UTC (rev 92386)
@@ -1,3 +1,21 @@
+2011-08-04  Filip Pizlo  <[email protected]>
+
+        Eval handling attempts literal parsing even when the eval
+        string is in the cache
+        https://bugs.webkit.org/show_bug.cgi?id=65675
+
+        Reviewed by Oliver Hunt.
+        
+        This is a 25% speed-up on date-format-tofte and a 1.5% speed-up overall
+        in SunSpider.  It's neutral on V8.
+
+        * bytecode/EvalCodeCache.h:
+        (JSC::EvalCodeCache::tryGet):
+        (JSC::EvalCodeCache::getSlow):
+        (JSC::EvalCodeCache::get):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::callEval):
+
 2011-08-03  Mark Rowe  <[email protected]>
 
         Bring some order to FeatureDefines.xcconfig to make it easier to follow.

Modified: trunk/Source/_javascript_Core/bytecode/EvalCodeCache.h (92385 => 92386)


--- trunk/Source/_javascript_Core/bytecode/EvalCodeCache.h	2011-08-04 17:48:06 UTC (rev 92385)
+++ trunk/Source/_javascript_Core/bytecode/EvalCodeCache.h	2011-08-04 17:48:40 UTC (rev 92386)
@@ -45,23 +45,33 @@
 
     class EvalCodeCache {
     public:
+        EvalExecutable* tryGet(bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain)
+        {
+            if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
+                return m_cacheMap.get(evalSource.impl()).get();
+            return 0;
+        }
+        
+        EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
+        {
+            EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
+            exceptionValue = evalExecutable->compile(exec, scopeChain);
+            if (exceptionValue)
+                return 0;
+            
+            if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
+                m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->globalData(), owner, evalExecutable));
+            
+            return evalExecutable;
+        }
+        
         EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
         {
-            EvalExecutable* evalExecutable = 0;
+            EvalExecutable* evalExecutable = tryGet(inStrictContext, evalSource, scopeChain);
 
-            if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
-                evalExecutable = m_cacheMap.get(evalSource.impl()).get();
+            if (!evalExecutable)
+                evalExecutable = getSlow(exec, owner, inStrictContext, evalSource, scopeChain, exceptionValue);
 
-            if (!evalExecutable) {
-                evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
-                exceptionValue = evalExecutable->compile(exec, scopeChain);
-                if (exceptionValue)
-                    return 0;
-
-                if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
-                    m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->globalData(), owner, evalExecutable));
-            }
-
             return evalExecutable;
         }
 

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (92385 => 92386)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2011-08-04 17:48:06 UTC (rev 92385)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2011-08-04 17:48:40 UTC (rev 92386)
@@ -437,22 +437,27 @@
         return JSValue();
     
     CodeBlock* codeBlock = callFrame->codeBlock();
-    if (!codeBlock->isStrictMode()) {
-        // FIXME: We can use the preparser in strict mode, we just need additional logic
-        // to prevent duplicates.
-        LiteralParser preparser(callFrame, programSource.characters(), programSource.length(), LiteralParser::NonStrictJSON);
-        if (JSValue parsedObject = preparser.tryLiteralParse())
-            return parsedObject;
-    }
-
+    
     ScopeChainNode* scopeChain = callFrame->scopeChain();
-    JSValue exceptionValue;
-    EvalExecutable* eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->ownerExecutable(), codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
+    EvalExecutable* eval = codeBlock->evalCodeCache().tryGet(codeBlock->isStrictMode(), programSource, scopeChain);
 
-    ASSERT(!eval == exceptionValue);
-    if (UNLIKELY(!eval))
-        return throwError(callFrame, exceptionValue);
+    if (!eval) {
+        if (!codeBlock->isStrictMode()) {
+            // FIXME: We can use the preparser in strict mode, we just need additional logic
+            // to prevent duplicates.
+            LiteralParser preparser(callFrame, programSource.characters(), programSource.length(), LiteralParser::NonStrictJSON);
+            if (JSValue parsedObject = preparser.tryLiteralParse())
+                return parsedObject;
+        }
 
+        JSValue exceptionValue;
+        eval = codeBlock->evalCodeCache().getSlow(callFrame, codeBlock->ownerExecutable(), codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
+        
+        ASSERT(!eval == exceptionValue);
+        if (UNLIKELY(!eval))
+            return throwError(callFrame, exceptionValue);
+    }
+
     JSValue thisValue = callFrame->uncheckedR(codeBlock->thisRegister()).jsValue();
     ASSERT(isValidThisObject(thisValue, callFrame));
     return callFrame->globalData().interpreter->execute(eval, callFrame, thisValue, callFrame->registers() - registerFile->begin() + registerOffset, scopeChain);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to