Title: [181482] trunk/Source/_javascript_Core
Revision
181482
Author
[email protected]
Date
2015-03-13 11:19:43 -0700 (Fri, 13 Mar 2015)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (181481 => 181482)


--- trunk/Source/_javascript_Core/ChangeLog	2015-03-13 18:02:40 UTC (rev 181481)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-03-13 18:19:43 UTC (rev 181482)
@@ -1,3 +1,23 @@
+2015-03-13  Ryosuke Niwa  <[email protected]>
+
+        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.
+
 2015-03-13  Mark Lam  <[email protected]>
 
         Introduce WTF::Atomic to wrap std::atomic for a friendlier CAS.

Modified: trunk/Source/_javascript_Core/runtime/CodeCache.cpp (181481 => 181482)


--- trunk/Source/_javascript_Core/runtime/CodeCache.cpp	2015-03-13 18:02:40 UTC (rev 181481)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.cpp	2015-03-13 18:19:43 UTC (rev 181482)
@@ -78,10 +78,10 @@
 UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserStrictness strictness, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
 {
     SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, strictness);
-    CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
+    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
     bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff && !vm.typeProfiler() && !vm.controlFlowProfiler();
-    if (!addResult.isNewEntry && canCache) {
-        UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast<UnlinkedCodeBlockType*>(addResult.iterator->value.cell.get());
+    if (cache && canCache) {
+        UnlinkedCodeBlockType* unlinkedCodeBlock = jsCast<UnlinkedCodeBlockType*>(cache->cell.get());
         unsigned firstLine = source.firstLine() + unlinkedCodeBlock->firstLine();
         unsigned lineCount = unlinkedCodeBlock->lineCount();
         unsigned startColumn = unlinkedCodeBlock->startColumn() + source.startColumn();
@@ -93,10 +93,9 @@
 
     typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
     std::unique_ptr<RootNode> rootNode = parse<RootNode>(&vm, source, 0, Identifier(), strictness, JSParseProgramCode, error);
-    if (!rootNode) {
-        m_sourceCode.remove(addResult.iterator);
-        return 0;
-    }
+    if (!rootNode)
+        return nullptr;
+
     unsigned lineCount = rootNode->lastLine() - rootNode->lineNo();
     unsigned startColumn = rootNode->startColumn() + 1;
     bool endColumnIsOnStartLine = !lineCount;
@@ -109,17 +108,13 @@
 
     auto generator = std::make_unique<BytecodeGenerator>(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode);
     error = generator->generate();
-    if (error.isValid()) {
-        m_sourceCode.remove(addResult.iterator);
+    if (error.isValid())
         return nullptr;
-    }
 
-    if (!canCache) {
-        m_sourceCode.remove(addResult.iterator);
+    if (!canCache)
         return unlinkedCodeBlock;
-    }
 
-    addResult.iterator->value = SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age());
+    m_sourceCode.addCache(key, SourceCodeValue(vm, unlinkedCodeBlock, m_sourceCode.age()));
     return unlinkedCodeBlock;
 }
 
@@ -136,15 +131,14 @@
 UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const Identifier& name, const SourceCode& source, ParserError& error)
 {
     SourceCodeKey key = SourceCodeKey(source, name.string(), SourceCodeKey::FunctionType, JSParseNormal);
-    CodeCacheMap::AddResult addResult = m_sourceCode.add(key, SourceCodeValue());
-    if (!addResult.isNewEntry)
-        return jsCast<UnlinkedFunctionExecutable*>(addResult.iterator->value.cell.get());
+    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
+    if (cache)
+        return jsCast<UnlinkedFunctionExecutable*>(cache->cell.get());
 
     JSTextPosition positionBeforeLastNewline;
     std::unique_ptr<ProgramNode> program = parse<ProgramNode>(&vm, source, 0, Identifier(), JSParseNormal, JSParseProgramCode, error, &positionBeforeLastNewline);
     if (!program) {
         RELEASE_ASSERT(error.isValid());
-        m_sourceCode.remove(addResult.iterator);
         return nullptr;
     }
 
@@ -165,7 +159,7 @@
     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, body, UnlinkedNormalFunction);
     functionExecutable->m_nameValue.set(vm, functionExecutable, jsString(&vm, name.string()));
 
-    addResult.iterator->value = SourceCodeValue(vm, functionExecutable, m_sourceCode.age());
+    m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
     return functionExecutable;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/CodeCache.h (181481 => 181482)


--- trunk/Source/_javascript_Core/runtime/CodeCache.h	2015-03-13 18:02:40 UTC (rev 181481)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.h	2015-03-13 18:19:43 UTC (rev 181482)
@@ -144,18 +144,15 @@
     {
     }
 
-    AddResult add(const SourceCodeKey& key, const SourceCodeValue& value)
+    SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key)
     {
         prune();
 
-        AddResult addResult = m_map.add(key, value);
-        if (addResult.isNewEntry) {
-            m_size += key.length();
-            m_age += key.length();
-            return addResult;
-        }
+        iterator findResult = m_map.find(key);
+        if (findResult == m_map.end())
+            return nullptr;
 
-        int64_t age = m_age - addResult.iterator->value.age;
+        int64_t age = m_age - findResult->value.age;
         if (age > m_capacity) {
             // A requested object is older than the cache's capacity. We can
             // infer that requested objects are subject to high eviction probability,
@@ -170,8 +167,21 @@
                 m_capacity = m_minCapacity;
         }
 
-        addResult.iterator->value.age = m_age;
+        findResult->value.age = m_age;
         m_age += key.length();
+
+        return &findResult->value;
+    }
+
+    AddResult addCache(const SourceCodeKey& key, const SourceCodeValue& value)
+    {
+        prune();
+
+        AddResult addResult = m_map.add(key, value);
+        ASSERT(addResult.isNewEntry);
+
+        m_size += key.length();
+        m_age += key.length();
         return addResult;
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to