Title: [97564] trunk/Source/_javascript_Core
Revision
97564
Author
[email protected]
Date
2011-10-15 14:44:50 -0700 (Sat, 15 Oct 2011)

Log Message

FunctionExecutable should expose the ability to create unattached FunctionCodeBlocks
https://bugs.webkit.org/show_bug.cgi?id=70157

Reviewed by Geoff Garen.
        
Added FunctionExecutable::produceCodeBlockFor() and rewired compileForCallInternal()
and compileForConstructInternal() to use this method. This required more cleanly
exposing some of CodeBlock's tiering functionality and moving the CompilationKind
enum to Executable.h, as this was the easiest way to make it available to the
declarations/definitions of CodeBlock, FunctionExecutable, and BytecodeGenerator.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::copyDataFrom):
(JSC::CodeBlock::copyDataFromAlternative):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::setAlternative):
* bytecompiler/BytecodeGenerator.h:
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
* runtime/Executable.h:
(JSC::FunctionExecutable::codeBlockFor):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (97563 => 97564)


--- trunk/Source/_javascript_Core/ChangeLog	2011-10-15 19:35:33 UTC (rev 97563)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-10-15 21:44:50 UTC (rev 97564)
@@ -1,3 +1,31 @@
+2011-10-14  Filip Pizlo  <[email protected]>
+
+        FunctionExecutable should expose the ability to create unattached FunctionCodeBlocks
+        https://bugs.webkit.org/show_bug.cgi?id=70157
+
+        Reviewed by Geoff Garen.
+        
+        Added FunctionExecutable::produceCodeBlockFor() and rewired compileForCallInternal()
+        and compileForConstructInternal() to use this method. This required more cleanly
+        exposing some of CodeBlock's tiering functionality and moving the CompilationKind
+        enum to Executable.h, as this was the easiest way to make it available to the
+        declarations/definitions of CodeBlock, FunctionExecutable, and BytecodeGenerator.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::copyDataFrom):
+        (JSC::CodeBlock::copyDataFromAlternative):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::setAlternative):
+        * bytecompiler/BytecodeGenerator.h:
+        * runtime/Executable.cpp:
+        (JSC::EvalExecutable::compileInternal):
+        (JSC::ProgramExecutable::compileInternal):
+        (JSC::FunctionExecutable::produceCodeBlockFor):
+        (JSC::FunctionExecutable::compileForCallInternal):
+        (JSC::FunctionExecutable::compileForConstructInternal):
+        * runtime/Executable.h:
+        (JSC::FunctionExecutable::codeBlockFor):
+
 2011-10-15  Laszlo Gombos  <[email protected]>
 
         [Qt] [Symbian] Remove support for the Symbian platform for the QtWebKit port

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (97563 => 97564)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-10-15 19:35:33 UTC (rev 97563)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2011-10-15 21:44:50 UTC (rev 97564)
@@ -1808,16 +1808,21 @@
         target[i] = source[i];
 }
 
-void CodeBlock::copyDataFromAlternative()
+void CodeBlock::copyDataFrom(CodeBlock* alternative)
 {
-    if (!m_alternative)
+    if (!alternative)
         return;
     
-    replaceExistingEntries(m_constantRegisters, m_alternative->m_constantRegisters);
-    replaceExistingEntries(m_functionDecls, m_alternative->m_functionDecls);
-    replaceExistingEntries(m_functionExprs, m_alternative->m_functionExprs);
+    replaceExistingEntries(m_constantRegisters, alternative->m_constantRegisters);
+    replaceExistingEntries(m_functionDecls, alternative->m_functionDecls);
+    replaceExistingEntries(m_functionExprs, alternative->m_functionExprs);
 }
 
+void CodeBlock::copyDataFromAlternative()
+{
+    copyDataFrom(m_alternative.get());
+}
+
 #if ENABLE(JIT)
 // FIXME: Implement OSR. If compileOptimized() is called from somewhere other than the
 // epilogue, do OSR from the old code block to the new one.

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (97563 => 97564)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-10-15 19:35:33 UTC (rev 97563)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2011-10-15 21:44:50 UTC (rev 97564)
@@ -248,6 +248,7 @@
         
         CodeBlock* alternative() { return m_alternative.get(); }
         PassOwnPtr<CodeBlock> releaseAlternative() { return m_alternative.release(); }
+        void setAlternative(PassOwnPtr<CodeBlock> alternative) { m_alternative = alternative; }
         
         void visitAggregate(SlotVisitor&);
 
@@ -732,6 +733,7 @@
 
         void shrinkToFit();
         
+        void copyDataFrom(CodeBlock* alternative);
         void copyDataFromAlternative();
         
         // Functions for controlling when tiered compilation kicks in. This
@@ -1106,7 +1108,7 @@
         // as we need to initialise the CodeBlock before we could initialise any RefPtr to hold the shared
         // symbol table, so we just pass as a raw pointer with a ref count of 1.  We then manually deref
         // in the destructor.
-        FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative)
+        FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative = nullptr)
             : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, SharedSymbolTable::create().leakRef(), isConstructor, alternative)
         {
         }

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (97563 => 97564)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2011-10-15 19:35:33 UTC (rev 97563)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2011-10-15 21:44:50 UTC (rev 97564)
@@ -92,8 +92,6 @@
         JS_EXPORT_PRIVATE static void setDumpsGeneratedCode(bool dumpsGeneratedCode);
         static bool dumpsGeneratedCode();
 
-        enum CompilationKind { FirstCompilation, OptimizingCompilation };
-        
         BytecodeGenerator(ProgramNode*, ScopeChainNode*, SymbolTable*, ProgramCodeBlock*, CompilationKind);
         BytecodeGenerator(FunctionBodyNode*, ScopeChainNode*, SymbolTable*, CodeBlock*, CompilationKind);
         BytecodeGenerator(EvalNode*, ScopeChainNode*, SymbolTable*, EvalCodeBlock*, CompilationKind);

Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (97563 => 97564)


--- trunk/Source/_javascript_Core/runtime/Executable.cpp	2011-10-15 19:35:33 UTC (rev 97563)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp	2011-10-15 21:44:50 UTC (rev 97564)
@@ -168,7 +168,7 @@
     OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
     ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
     m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release()));
-    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? BytecodeGenerator::OptimizingCompilation : BytecodeGenerator::FirstCompilation)));
+    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
     if ((exception = generator->generate())) {
         m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
         evalNode->destroyData();
@@ -298,7 +298,7 @@
     OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release();
     ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
     m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release()));
-    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? BytecodeGenerator::OptimizingCompilation : BytecodeGenerator::FirstCompilation)));
+    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
     if ((exception = generator->generate())) {
         m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative());
         programNode->destroyData();
@@ -406,17 +406,14 @@
     return error;
 }
 
-JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec, JITCode::JITType jitType)
+PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ExecState* exec, ScopeChainNode* scopeChainNode, CompilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception)
 {
-#if !ENABLE(JIT)
-    UNUSED_PARAM(jitType);
-#endif
-    JSObject* exception = 0;
+    exception = 0;
     JSGlobalData* globalData = scopeChainNode->globalData;
     RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
     if (!body) {
         ASSERT(exception);
-        return exception;
+        return nullptr;
     }
     if (m_forceUsesArguments)
         body->setUsesArguments();
@@ -425,26 +422,42 @@
 
     JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
 
-    OwnPtr<CodeBlock> previousCodeBlock = m_codeBlockForCall.release();
-    ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
-    m_codeBlockForCall = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), false, previousCodeBlock.release()));
-    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChainNode, m_codeBlockForCall->symbolTable(), m_codeBlockForCall.get(), !!m_codeBlockForCall->alternative() ? BytecodeGenerator::OptimizingCompilation : BytecodeGenerator::FirstCompilation)));
-    if ((exception = generator->generate())) {
-        m_codeBlockForCall = static_pointer_cast<FunctionCodeBlock>(m_codeBlockForCall->releaseAlternative());
-        body->destroyData();
+    OwnPtr<FunctionCodeBlock> result;
+    ASSERT((compilationKind == FirstCompilation) == !codeBlockFor(specializationKind));
+    result = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), specializationKind == CodeForConstruct));
+    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChainNode, result->symbolTable(), result.get(), compilationKind)));
+    exception = generator->generate();
+    body->destroyData();
+    if (exception)
+        return nullptr;
+
+    result->copyDataFrom(codeBlockFor(specializationKind).get());
+    return result.release();
+}
+
+JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec, JITCode::JITType jitType)
+{
+#if !ENABLE(JIT)
+    UNUSED_PARAM(jitType);
+#endif
+    JSObject* exception;
+    JSGlobalData* globalData = scopeChainNode->globalData;
+    
+    ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall);
+    OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(exec, scopeChainNode, !!m_codeBlockForCall ? OptimizingCompilation : FirstCompilation, CodeForCall, exception);
+    if (!newCodeBlock)
         return exception;
-    }
 
+    newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_codeBlockForCall.release()));
+    m_codeBlockForCall = newCodeBlock.release();
+    
     m_numParametersForCall = m_codeBlockForCall->m_numParameters;
     ASSERT(m_numParametersForCall);
     m_numCapturedVariables = m_codeBlockForCall->m_numCapturedVars;
     m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
 
-    body->destroyData();
-    m_codeBlockForCall->copyDataFromAlternative();
-
 #if ENABLE(JIT)
-    if (exec->globalData().canUseJIT()) {
+    if (globalData->canUseJIT()) {
         bool dfgCompiled = false;
         if (jitType == JITCode::DFGJIT)
             dfgCompiled = DFG::tryCompileFunction(exec, calleeArgsExec, m_codeBlockForCall.get(), m_jitCodeForCall, m_jitCodeForCallWithArityCheck);
@@ -457,7 +470,7 @@
                 m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
                 return 0;
             }
-            m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
+            m_jitCodeForCall = JIT::compile(globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
         }
 #if !ENABLE(OPCODE_SAMPLING)
         if (!BytecodeGenerator::dumpsGeneratedCode())
@@ -488,40 +501,24 @@
 {
     UNUSED_PARAM(jitType);
     
-    JSObject* exception = 0;
+    JSObject* exception;
     JSGlobalData* globalData = scopeChainNode->globalData;
-    RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
-    if (!body) {
-        ASSERT(exception);
+    
+    ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct);
+    OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(exec, scopeChainNode, !!m_codeBlockForConstruct ? OptimizingCompilation : FirstCompilation, CodeForConstruct, exception);
+    if (!newCodeBlock)
         return exception;
-    }
-    if (m_forceUsesArguments)
-        body->setUsesArguments();
-    body->finishParsing(m_parameters, m_name);
-    recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine());
 
-    JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
-
-    OwnPtr<CodeBlock> previousCodeBlock = m_codeBlockForConstruct.release();
-    ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
-    m_codeBlockForConstruct = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), true, previousCodeBlock.release()));
-    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChainNode, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct.get(), !!m_codeBlockForConstruct->alternative() ? BytecodeGenerator::OptimizingCompilation : BytecodeGenerator::FirstCompilation)));
-    if ((exception = generator->generate())) {
-        m_codeBlockForConstruct = static_pointer_cast<FunctionCodeBlock>(m_codeBlockForConstruct->releaseAlternative());
-        body->destroyData();
-        return exception;
-    }
-
+    newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_codeBlockForConstruct.release()));
+    m_codeBlockForConstruct = newCodeBlock.release();
+    
     m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters;
     ASSERT(m_numParametersForConstruct);
     m_numCapturedVariables = m_codeBlockForConstruct->m_numCapturedVars;
     m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
 
-    body->destroyData();
-    m_codeBlockForConstruct->copyDataFromAlternative();
-
 #if ENABLE(JIT)
-    if (exec->globalData().canUseJIT()) {
+    if (globalData->canUseJIT()) {
         bool dfgCompiled = false;
         if (jitType == JITCode::DFGJIT)
             dfgCompiled = DFG::tryCompileFunction(exec, calleeArgsExec, m_codeBlockForConstruct.get(), m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck);
@@ -534,7 +531,7 @@
                 m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
                 return 0;
             }
-            m_jitCodeForConstruct = JIT::compile(scopeChainNode->globalData, m_codeBlockForConstruct.get(), &m_jitCodeForConstructWithArityCheck);
+            m_jitCodeForConstruct = JIT::compile(globalData, m_codeBlockForConstruct.get(), &m_jitCodeForConstructWithArityCheck);
         }
 #if !ENABLE(OPCODE_SAMPLING)
         if (!BytecodeGenerator::dumpsGeneratedCode())

Modified: trunk/Source/_javascript_Core/runtime/Executable.h (97563 => 97564)


--- trunk/Source/_javascript_Core/runtime/Executable.h	2011-10-15 19:35:33 UTC (rev 97563)
+++ trunk/Source/_javascript_Core/runtime/Executable.h	2011-10-15 21:44:50 UTC (rev 97564)
@@ -45,6 +45,7 @@
     struct ExceptionInfo;
     
     enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
+    enum CompilationKind { FirstCompilation, OptimizingCompilation };
 
     class ExecutableBase : public JSCell {
         friend class JIT;
@@ -460,6 +461,8 @@
             ASSERT(m_codeBlockForConstruct);
             return *m_codeBlockForConstruct;
         }
+        
+        PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(ExecState*, ScopeChainNode*, CompilationKind, CodeSpecializationKind, JSObject*& exception);
 
         JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode, ExecState* calleeArgsExec = 0)
         {
@@ -606,6 +609,14 @@
         JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec, JITCode::JITType);
         JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, ExecState* calleeArgsExec, JITCode::JITType);
         
+        OwnPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind)
+        {
+            if (kind == CodeForCall)
+                return m_codeBlockForCall;
+            ASSERT(kind == CodeForConstruct);
+            return m_codeBlockForConstruct;
+        }
+        
         static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags;
         unsigned m_numCapturedVariables : 31;
         bool m_forceUsesArguments : 1;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to