Changeset 136261 in webkit


Ignore:
Timestamp:
Nov 30, 2012 1:09:21 PM (11 years ago)
Author:
oliver@apple.com
Message:

Add direct string->function code cache
https://bugs.webkit.org/show_bug.cgi?id=103764

Reviewed by Michael Saboff.

A fairly logically simple patch. We now track the start of the
unique portion of a functions body, and use that as our key for
unlinked function code. This allows us to cache identical code
in different contexts, leading to a small but consistent improvement
on the benchmarks we track.

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedFunctionExecutable::functionStartOffset):
(UnlinkedFunctionExecutable):

  • parser/ASTBuilder.h:

(ASTBuilder):
(JSC::ASTBuilder::setFunctionStart):

  • parser/Nodes.cpp:
  • parser/Nodes.h:

(JSC::FunctionBodyNode::setFunctionStart):
(JSC::FunctionBodyNode::functionStart):
(FunctionBodyNode):

  • parser/Parser.cpp:

(JSC::::parseFunctionInfo):

  • parser/Parser.h:

(JSC::Parser::findCachedFunctionInfo):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::setFunctionStart):

  • runtime/CodeCache.cpp:

(JSC::CodeCache::generateFunctionCodeBlock):
(JSC::CodeCache::getFunctionCodeBlock):
(JSC::CodeCache::usedFunctionCode):

  • runtime/CodeCache.h:
Location:
trunk/Source/JavaScriptCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r136246 r136261  
     12012-11-30  Oliver Hunt  <oliver@apple.com>
     2
     3        Add direct string->function code cache
     4        https://bugs.webkit.org/show_bug.cgi?id=103764
     5
     6        Reviewed by Michael Saboff.
     7
     8        A fairly logically simple patch.  We now track the start of the
     9        unique portion of a functions body, and use that as our key for
     10        unlinked function code.  This allows us to cache identical code
     11        in different contexts, leading to a small but consistent improvement
     12        on the benchmarks we track.
     13
     14        * bytecode/UnlinkedCodeBlock.cpp:
     15        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
     16        * bytecode/UnlinkedCodeBlock.h:
     17        (JSC::UnlinkedFunctionExecutable::functionStartOffset):
     18        (UnlinkedFunctionExecutable):
     19        * parser/ASTBuilder.h:
     20        (ASTBuilder):
     21        (JSC::ASTBuilder::setFunctionStart):
     22        * parser/Nodes.cpp:
     23        * parser/Nodes.h:
     24        (JSC::FunctionBodyNode::setFunctionStart):
     25        (JSC::FunctionBodyNode::functionStart):
     26        (FunctionBodyNode):
     27        * parser/Parser.cpp:
     28        (JSC::::parseFunctionInfo):
     29        * parser/Parser.h:
     30        (JSC::Parser::findCachedFunctionInfo):
     31        * parser/SyntaxChecker.h:
     32        (JSC::SyntaxChecker::setFunctionStart):
     33        * runtime/CodeCache.cpp:
     34        (JSC::CodeCache::generateFunctionCodeBlock):
     35        (JSC::CodeCache::getFunctionCodeBlock):
     36        (JSC::CodeCache::usedFunctionCode):
     37        * runtime/CodeCache.h:
     38
    1392012-11-30  Allan Sandfeld Jensen  <allan.jensen@digia.com>
    240
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp

    r133975 r136261  
    6767    , m_firstLineOffset(node->firstLine() - source.firstLine())
    6868    , m_lineCount(node->lastLine() - node->firstLine())
     69    , m_functionStartOffset(node->functionStart() - source.startOffset())
    6970    , m_startOffset(node->source().startOffset() - source.startOffset())
    7071    , m_sourceLength(node->source().length())
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r133975 r136261  
    9999    unsigned firstLineOffset() const { return m_firstLineOffset; }
    100100    unsigned lineCount() const { return m_lineCount; }
     101    unsigned functionStartOffset() const { return m_functionStartOffset; }
    101102    unsigned startOffset() const { return m_startOffset; }
    102103    unsigned sourceLength() { return m_sourceLength; }
     
    154155    unsigned m_firstLineOffset;
    155156    unsigned m_lineCount;
     157    unsigned m_functionStartOffset;
    156158    unsigned m_startOffset;
    157159    unsigned m_sourceLength;
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r127987 r136261  
    268268        return FunctionBodyNode::create(m_globalData, location, inStrictContext);
    269269    }
     270
     271    void setFunctionStart(FunctionBodyNode* body, int functionStart)
     272    {
     273        body->setFunctionStart(functionStart);
     274    }
    270275   
    271276    template <bool> PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
  • trunk/Source/JavaScriptCore/parser/Nodes.cpp

    r129773 r136261  
    4242#include "RegExpObject.h"
    4343#include "SamplingTool.h"
     44#include "SourceProviderCacheItem.h"
    4445#include <wtf/Assertions.h>
    4546#include <wtf/RefCountedLeakCounter.h>
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r128234 r136261  
    4747    class JSScope;
    4848    class ScopeNode;
     49    class SourceProviderCacheItem;
    4950
    5051    typedef unsigned CodeFeatures;
     
    14251426        FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
    14261427
     1428        void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
     1429        int functionStart() const { return m_functionStart; }
     1430
    14271431        static const bool scopeIsFunction = true;
    14281432
     
    14351439        FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
    14361440        RefPtr<FunctionParameters> m_parameters;
     1441        int m_functionStart;
    14371442    };
    14381443
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r136049 r136261  
    843843       
    844844        closeBracePos = cachedInfo->closeBracePos;
     845        context.setFunctionStart(body, functionStart);
    845846        m_token = cachedInfo->closeBraceToken();
    846847        m_lexer->setOffset(m_token.m_location.endOffset);
     
    870871        functionScope->saveFunctionInfo(newInfo.get());
    871872    }
    872    
     873    context.setFunctionStart(body, functionStart);
     874
    873875    failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
    874876    matchOrFail(CLOSEBRACE);
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r133688 r136261  
    510510    ScopeStack m_scopeStack;
    511511   
    512     const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos) 
     512    const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)
    513513    {
    514514        return m_functionCache ? m_functionCache->get(openBracePos) : 0;
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r127958 r136261  
    152152    ExpressionType createFunctionExpr(const JSTokenLocation&, const Identifier*, int, int, int, int, int, int) { return FunctionExpr; }
    153153    int createFunctionBody(const JSTokenLocation&, bool) { return 1; }
     154    void setFunctionStart(int, int) { }
    154155    int createArguments() { return 1; }
    155156    int createArguments(int) { return 1; }
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r133975 r136261  
    127127    if (error.m_type != ParserError::ErrorNone)
    128128        return 0;
    129     m_cachedFunctionCode.add(result, Strong<UnlinkedFunctionCodeBlock>(globalData, result));
     129    m_recentlyUsedFunctionCode.add(result, Strong<UnlinkedFunctionCodeBlock>(globalData, result));
    130130    return result;
    131131}
     
    133133UnlinkedFunctionCodeBlock* CodeCache::getFunctionCodeBlock(JSGlobalData& globalData, UnlinkedFunctionExecutable* executable, const SourceCode& source, CodeSpecializationKind kind, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
    134134{
    135     return generateFunctionCodeBlock(globalData, executable, source, kind, debuggerMode, profilerMode, error);
     135    if (debuggerMode == DebuggerOn || profilerMode == ProfilerOn)
     136        return generateFunctionCodeBlock(globalData, executable, source, kind, debuggerMode, profilerMode, error);
     137
     138    SourceCode functionSource(source.provider(), executable->functionStartOffset(), source.endOffset(), source.firstLine());
     139    CodeBlockKey key = makeCodeBlockKey(functionSource, kind == CodeForCall ? FunctionCallType : FunctionConstructType, executable->isInStrictContext() ? JSParseStrict : JSParseNormal);
     140    if (const Strong<UnlinkedFunctionCodeBlock>* cacheEntry = m_cachedFunctionExecutables.find(key)) {
     141        if (cacheEntry) {
     142            UnlinkedFunctionCodeBlock* unlinkedCode = cacheEntry->get();
     143            unsigned firstLine = source.firstLine() + unlinkedCode->firstLine();
     144            executable->recordParse(unlinkedCode->codeFeatures(), unlinkedCode->hasCapturedVariables(), firstLine, firstLine + unlinkedCode->lineCount());
     145            m_recentlyUsedFunctionCode.add(unlinkedCode, *cacheEntry);
     146            return unlinkedCode;
     147        }
     148    }
     149    UnlinkedFunctionCodeBlock* result = generateFunctionCodeBlock(globalData, executable, source, kind, debuggerMode, profilerMode, error);
     150    m_cachedFunctionExecutables.add(key, Strong<UnlinkedFunctionCodeBlock>(globalData, result));
     151    return result;
    136152}
    137153
     
    174190void CodeCache::usedFunctionCode(JSGlobalData& globalData, UnlinkedFunctionCodeBlock* codeBlock)
    175191{
    176     m_cachedFunctionCode.add(codeBlock, Strong<UnlinkedFunctionCodeBlock>(globalData, codeBlock));
     192    m_recentlyUsedFunctionCode.add(codeBlock, Strong<UnlinkedFunctionCodeBlock>(globalData, codeBlock));
    177193}
    178194
  • trunk/Source/JavaScriptCore/runtime/CodeCache.h

    r134993 r136261  
    4141
    4242class EvalExecutable;
     43class FunctionBodyNode;
    4344class Identifier;
    4445class ProgramExecutable;
     
    99100    ~CodeCache();
    100101
    101     enum CodeType { EvalType, ProgramType, FunctionType };
     102    enum CodeType { EvalType, ProgramType, FunctionCallType, FunctionConstructType };
    102103    typedef std::pair<String, unsigned> CodeBlockKey;
    103104    typedef std::pair<String, String> GlobalFunctionKey;
     
    119120
    120121    CacheMap<CodeBlockKey, Strong<UnlinkedCodeBlock>, kMaxCodeBlockEntries> m_cachedCodeBlocks;
    121     CacheMap<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable>, kMaxGlobalFunctionEntries> m_cachedGlobalFunctions;
    122     CacheMap<UnlinkedFunctionCodeBlock*, Strong<UnlinkedFunctionCodeBlock>, kMaxFunctionCodeBlocks> m_cachedFunctionCode;
     122    CacheMap<CodeBlockKey, Strong<UnlinkedFunctionCodeBlock>, kMaxFunctionCodeBlocks> m_cachedFunctionExecutables;
     123    CacheMap<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable>, kMaxFunctionCodeBlocks> m_cachedGlobalFunctions;
     124    CacheMap<UnlinkedFunctionCodeBlock*, Strong<UnlinkedFunctionCodeBlock>, kMaxFunctionCodeBlocks> m_recentlyUsedFunctionCode;
    123125};
    124126
Note: See TracChangeset for help on using the changeset viewer.