⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 181482 in webkit


Ignore:
Timestamp:
Mar 13, 2015, 11:19:43 AM (11 years ago)
Author:
rniwa@webkit.org
Message:

BytecodeGenerator needs to be re-entrant to support miranda functions
https://bugs.webkit.org/show_bug.cgi?id=142627

Reviewed by Filip Pizlo.

Made CodeCache::getGlobalCodeBlock and CodeCache::getFunctionExecutableFromGlobalCode re-entrant
by not keeping AddResult while invoking BytecodeGenerator::generate.

This is needed to support Miranda functions since they need to be lazily initialized.

  • runtime/CodeCache.cpp:

(JSC::CodeCache::getGlobalCodeBlock):
(JSC::CodeCache::getFunctionExecutableFromGlobalCode):

  • runtime/CodeCache.h:

(JSC::CodeCacheMap::findCacheAndUpdateAge): Extracted from add.
(JSC::CodeCacheMap::addCache): Extracted from add.
(JSC::CodeCacheMap::add): Deleted.

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r181481 r181482  
     12015-03-13  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        BytecodeGenerator needs to be re-entrant to support miranda functions
     4        https://bugs.webkit.org/show_bug.cgi?id=142627
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Made CodeCache::getGlobalCodeBlock and CodeCache::getFunctionExecutableFromGlobalCode re-entrant
     9        by not keeping AddResult while invoking BytecodeGenerator::generate.
     10
     11        This is needed to support Miranda functions since they need to be lazily initialized.
     12
     13        * runtime/CodeCache.cpp:
     14        (JSC::CodeCache::getGlobalCodeBlock):
     15        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
     16        * runtime/CodeCache.h:
     17        (JSC::CodeCacheMap::findCacheAndUpdateAge): Extracted from add.
     18        (JSC::CodeCacheMap::addCache): Extracted from add.
     19        (JSC::CodeCacheMap::add): Deleted.
     20
    1212015-03-13  Mark Lam  <mark.lam@apple.com>
    222
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r180637 r181482  
    7979{
    8080    SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, strictness);
    81     CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
     81    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
    8282    bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff && !vm.typeProfiler() && !vm.controlFlowProfiler();
    83     if (!addResult.isNewEntry && canCache) {
    84         UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast<UnlinkedCodeBlockType*>(addResult.iterator->value.cell.get());
     83    if (cache && canCache) {
     84        UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast<UnlinkedCodeBlockType*>(cache->cell.get());
    8585        unsigned firstLine = source.firstLine() + unlinkedCodeBlock->firstLine();
    8686        unsigned lineCount = unlinkedCodeBlock->lineCount();
     
    9494    typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
    9595    std::unique_ptr<RootNode> rootNode = parse<RootNode>(&vm, source, 0, Identifier(), strictness, JSParseProgramCode, error);
    96     if (!rootNode) {
    97         m_sourceCode.remove(addResult.iterator);
    98         return 0;
    99     }
     96    if (!rootNode)
     97        return nullptr;
     98
    10099    unsigned lineCount = rootNode->lastLine() - rootNode->lineNo();
    101100    unsigned startColumn = rootNode->startColumn() + 1;
     
    110109    auto generator = std::make_unique<BytecodeGenerator>(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode);
    111110    error = generator->generate();
    112     if (error.isValid()) {
    113         m_sourceCode.remove(addResult.iterator);
     111    if (error.isValid())
    114112        return nullptr;
    115     }
    116113
    117     if (!canCache) {
    118         m_sourceCode.remove(addResult.iterator);
     114    if (!canCache)
    119115        return unlinkedCodeBlock;
    120     }
    121116
    122     addResult.iterator->value = SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age());
     117    m_sourceCode.addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age()));
    123118    return unlinkedCodeBlock;
    124119}
     
    137132{
    138133    SourceCodeKey key = SourceCodeKey(source, name.string(), SourceCodeKey::FunctionType, JSParseNormal);
    139     CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
    140     if (!addResult.isNewEntry)
    141         return jsCast<UnlinkedFunctionExecutable*>(addResult.iterator->value.cell.get());
     134    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
     135    if (cache)
     136        return jsCast<UnlinkedFunctionExecutable*>(cache->cell.get());
    142137
    143138    JSTextPosition positionBeforeLastNewline;
     
    145140    if (!program) {
    146141        RELEASE_ASSERT(error.isValid());
    147         m_sourceCode.remove(addResult.iterator);
    148142        return nullptr;
    149143    }
     
    166160    functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
    167161
    168     addResult.iterator->value = SourceCodeValue(vm, functionExecutable, m_sourceCode.age());
     162    m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
    169163    return functionExecutable;
    170164}
  • trunk/Source/JavaScriptCore/runtime/CodeCache.h

    r180637 r181482  
    145145    }
    146146
    147     AddResult add(const SourceCodeKey& key, const SourceCodeValue& value)
     147    SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key)
    148148    {
    149149        prune();
    150150
    151         AddResult addResult = m_map.add(key, value);
    152         if (addResult.isNewEntry) {
    153             m_size += key.length();
    154             m_age += key.length();
    155             return addResult;
    156         }
    157 
    158         int64_t age = m_age - addResult.iterator->value.age;
     151        iterator findResult = m_map.find(key);
     152        if (findResult == m_map.end())
     153            return nullptr;
     154
     155        int64_t age = m_age - findResult->value.age;
    159156        if (age > m_capacity) {
    160157            // A requested object is older than the cache's capacity. We can
     
    171168        }
    172169
    173         addResult.iterator->value.age = m_age;
     170        findResult->value.age = m_age;
     171        m_age += key.length();
     172
     173        return &findResult->value;
     174    }
     175
     176    AddResult addCache(const SourceCodeKey& key, const SourceCodeValue& value)
     177    {
     178        prune();
     179
     180        AddResult addResult = m_map.add(key, value);
     181        ASSERT(addResult.isNewEntry);
     182
     183        m_size += key.length();
    174184        m_age += key.length();
    175185        return addResult;
Note: See TracChangeset for help on using the changeset viewer.