Changeset 92386 in webkit


Ignore:
Timestamp:
Aug 4, 2011 10:48:40 AM (13 years ago)
Author:
fpizlo@apple.com
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):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r92333 r92386  
     12011-08-04  Filip Pizlo  <fpizlo@apple.com>
     2
     3        Eval handling attempts literal parsing even when the eval
     4        string is in the cache
     5        https://bugs.webkit.org/show_bug.cgi?id=65675
     6
     7        Reviewed by Oliver Hunt.
     8       
     9        This is a 25% speed-up on date-format-tofte and a 1.5% speed-up overall
     10        in SunSpider.  It's neutral on V8.
     11
     12        * bytecode/EvalCodeCache.h:
     13        (JSC::EvalCodeCache::tryGet):
     14        (JSC::EvalCodeCache::getSlow):
     15        (JSC::EvalCodeCache::get):
     16        * interpreter/Interpreter.cpp:
     17        (JSC::Interpreter::callEval):
     18
    1192011-08-03  Mark Rowe  <mrowe@apple.com>
    220
  • trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h

    r89885 r92386  
    4646    class EvalCodeCache {
    4747    public:
     48        EvalExecutable* tryGet(bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain)
     49        {
     50            if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
     51                return m_cacheMap.get(evalSource.impl()).get();
     52            return 0;
     53        }
     54       
     55        EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
     56        {
     57            EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
     58            exceptionValue = evalExecutable->compile(exec, scopeChain);
     59            if (exceptionValue)
     60                return 0;
     61           
     62            if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
     63                m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->globalData(), owner, evalExecutable));
     64           
     65            return evalExecutable;
     66        }
     67       
    4868        EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
    4969        {
    50             EvalExecutable* evalExecutable = 0;
     70            EvalExecutable* evalExecutable = tryGet(inStrictContext, evalSource, scopeChain);
    5171
    52             if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject())
    53                 evalExecutable = m_cacheMap.get(evalSource.impl()).get();
    54 
    55             if (!evalExecutable) {
    56                 evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext);
    57                 exceptionValue = evalExecutable->compile(exec, scopeChain);
    58                 if (exceptionValue)
    59                     return 0;
    60 
    61                 if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries)
    62                     m_cacheMap.set(evalSource.impl(), WriteBarrier<EvalExecutable>(exec->globalData(), owner, evalExecutable));
    63             }
     72            if (!evalExecutable)
     73                evalExecutable = getSlow(exec, owner, inStrictContext, evalSource, scopeChain, exceptionValue);
    6474
    6575            return evalExecutable;
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r91952 r92386  
    438438   
    439439    CodeBlock* codeBlock = callFrame->codeBlock();
    440     if (!codeBlock->isStrictMode()) {
    441         // FIXME: We can use the preparser in strict mode, we just need additional logic
    442         // to prevent duplicates.
    443         LiteralParser preparser(callFrame, programSource.characters(), programSource.length(), LiteralParser::NonStrictJSON);
    444         if (JSValue parsedObject = preparser.tryLiteralParse())
    445             return parsedObject;
    446     }
    447 
     440   
    448441    ScopeChainNode* scopeChain = callFrame->scopeChain();
    449     JSValue exceptionValue;
    450     EvalExecutable* eval = codeBlock->evalCodeCache().get(callFrame, codeBlock->ownerExecutable(), codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
    451 
    452     ASSERT(!eval == exceptionValue);
    453     if (UNLIKELY(!eval))
    454         return throwError(callFrame, exceptionValue);
     442    EvalExecutable* eval = codeBlock->evalCodeCache().tryGet(codeBlock->isStrictMode(), programSource, scopeChain);
     443
     444    if (!eval) {
     445        if (!codeBlock->isStrictMode()) {
     446            // FIXME: We can use the preparser in strict mode, we just need additional logic
     447            // to prevent duplicates.
     448            LiteralParser preparser(callFrame, programSource.characters(), programSource.length(), LiteralParser::NonStrictJSON);
     449            if (JSValue parsedObject = preparser.tryLiteralParse())
     450                return parsedObject;
     451        }
     452
     453        JSValue exceptionValue;
     454        eval = codeBlock->evalCodeCache().getSlow(callFrame, codeBlock->ownerExecutable(), codeBlock->isStrictMode(), programSource, scopeChain, exceptionValue);
     455       
     456        ASSERT(!eval == exceptionValue);
     457        if (UNLIKELY(!eval))
     458            return throwError(callFrame, exceptionValue);
     459    }
    455460
    456461    JSValue thisValue = callFrame->uncheckedR(codeBlock->thisRegister()).jsValue();
Note: See TracChangeset for help on using the changeset viewer.