Title: [187033] trunk/Source/_javascript_Core
Revision
187033
Author
saambara...@gmail.com
Date
2015-07-20 14:16:41 -0700 (Mon, 20 Jul 2015)

Log Message

"let" scoping introduced incoherent story about symbol table cloning
https://bugs.webkit.org/show_bug.cgi?id=147046

Reviewed by Filip Pizlo.

This patch now establishes a clear set of rules for how SymbolTables
are owned by CodeBlock. Every SymbolTable that is used by a bytecode
instruction must live in CodeBlock's constant register pool. When CodeBlock
is being linked, it ensures that every SymbolTable in the constant pool is cloned. 
This leaves no room for an un-cloned symbol table to be used by a bytecode instruction. 
Some instructions may refer to SymbolTable's indirectly through a JSLexicalEnvironment. 
This is fine, all JSLexicalEnvironment's are allocated with references to cloned symbol tables.

Another goal of this patch is to remove the notion that a SymbolTable is 1 to 1 
with a CodeBlock. With lexical scoping, this view of the world is no longer
correct. This patch begins to remove this assumption by making CodeBlock's
symbolTable() getter method private. There is still one place where we need
to purge our codebase of this assumption and that is the type profiler. It 
has not been updated for lexical scoping. After it is updated in 
https://bugs.webkit.org/show_bug.cgi?id=145438
we will be able to remove CodeBlock's symbolTable() getter entirely.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::nameForRegister):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::addStringSwitchJumpTable):
(JSC::CodeBlock::stringSwitchJumpTable):
(JSC::CodeBlock::evalCodeCache):
(JSC::CodeBlock::symbolTable):
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedFunctionExecutable::visitChildren):
(JSC::UnlinkedFunctionExecutable::link):
(JSC::UnlinkedFunctionExecutable::codeBlockFor):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::addExceptionHandler):
(JSC::UnlinkedCodeBlock::exceptionHandler):
(JSC::UnlinkedCodeBlock::setSymbolTableConstantIndex):
(JSC::UnlinkedCodeBlock::symbolTableConstantIndex):
(JSC::UnlinkedCodeBlock::symbolTable): Deleted.
(JSC::UnlinkedCodeBlock::setSymbolTable): Deleted.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::pushLexicalScope):
(JSC::BytecodeGenerator::variableForLocalEntry):
(JSC::BytecodeGenerator::createVariable):
(JSC::BytecodeGenerator::resolveType):
(JSC::BytecodeGenerator::emitResolveScope):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::thisRegister):
(JSC::BytecodeGenerator::instructions):
(JSC::BytecodeGenerator::symbolTable): Deleted.
* dfg/DFGGraph.h:
(JSC::DFG::Graph::baselineCodeBlockFor):
(JSC::DFG::Graph::isStrictModeFor):
(JSC::DFG::Graph::symbolTableFor): Deleted.
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::baselineCodeBlock):
(JSC::AssemblyHelpers::argumentsStart):
(JSC::AssemblyHelpers::symbolTableFor): Deleted.
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/Executable.cpp:
(JSC::FunctionExecutable::visitChildren):
(JSC::FunctionExecutable::clearUnlinkedCodeForRecompilation):
(JSC::FunctionExecutable::symbolTable): Deleted.
* runtime/Executable.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (187032 => 187033)


--- trunk/Source/_javascript_Core/ChangeLog	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-07-20 21:16:41 UTC (rev 187033)
@@ -1,3 +1,74 @@
+2015-07-20  Saam barati  <saambara...@gmail.com>
+
+        "let" scoping introduced incoherent story about symbol table cloning
+        https://bugs.webkit.org/show_bug.cgi?id=147046
+
+        Reviewed by Filip Pizlo.
+
+        This patch now establishes a clear set of rules for how SymbolTables
+        are owned by CodeBlock. Every SymbolTable that is used by a bytecode
+        instruction must live in CodeBlock's constant register pool. When CodeBlock
+        is being linked, it ensures that every SymbolTable in the constant pool is cloned. 
+        This leaves no room for an un-cloned symbol table to be used by a bytecode instruction. 
+        Some instructions may refer to SymbolTable's indirectly through a JSLexicalEnvironment. 
+        This is fine, all JSLexicalEnvironment's are allocated with references to cloned symbol tables.
+
+        Another goal of this patch is to remove the notion that a SymbolTable is 1 to 1 
+        with a CodeBlock. With lexical scoping, this view of the world is no longer
+        correct. This patch begins to remove this assumption by making CodeBlock's
+        symbolTable() getter method private. There is still one place where we need
+        to purge our codebase of this assumption and that is the type profiler. It 
+        has not been updated for lexical scoping. After it is updated in 
+        https://bugs.webkit.org/show_bug.cgi?id=145438
+        we will be able to remove CodeBlock's symbolTable() getter entirely.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        (JSC::CodeBlock::nameForRegister):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::addStringSwitchJumpTable):
+        (JSC::CodeBlock::stringSwitchJumpTable):
+        (JSC::CodeBlock::evalCodeCache):
+        (JSC::CodeBlock::symbolTable):
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedFunctionExecutable::visitChildren):
+        (JSC::UnlinkedFunctionExecutable::link):
+        (JSC::UnlinkedFunctionExecutable::codeBlockFor):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::addExceptionHandler):
+        (JSC::UnlinkedCodeBlock::exceptionHandler):
+        (JSC::UnlinkedCodeBlock::setSymbolTableConstantIndex):
+        (JSC::UnlinkedCodeBlock::symbolTableConstantIndex):
+        (JSC::UnlinkedCodeBlock::symbolTable): Deleted.
+        (JSC::UnlinkedCodeBlock::setSymbolTable): Deleted.
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::pushLexicalScope):
+        (JSC::BytecodeGenerator::variableForLocalEntry):
+        (JSC::BytecodeGenerator::createVariable):
+        (JSC::BytecodeGenerator::resolveType):
+        (JSC::BytecodeGenerator::emitResolveScope):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::thisRegister):
+        (JSC::BytecodeGenerator::instructions):
+        (JSC::BytecodeGenerator::symbolTable): Deleted.
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::baselineCodeBlockFor):
+        (JSC::DFG::Graph::isStrictModeFor):
+        (JSC::DFG::Graph::symbolTableFor): Deleted.
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::baselineCodeBlock):
+        (JSC::AssemblyHelpers::argumentsStart):
+        (JSC::AssemblyHelpers::symbolTableFor): Deleted.
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/Executable.cpp:
+        (JSC::FunctionExecutable::visitChildren):
+        (JSC::FunctionExecutable::clearUnlinkedCodeForRecompilation):
+        (JSC::FunctionExecutable::symbolTable): Deleted.
+        * runtime/Executable.h:
+
 2015-07-18  Filip Pizlo  <fpi...@apple.com>
 
         REGRESSION(186691): OSR entry is broken on loop headers that have no live variables

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (187032 => 187033)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2015-07-20 21:16:41 UTC (rev 187033)
@@ -1750,8 +1750,6 @@
     ASSERT(m_heap->isDeferred());
     ASSERT(m_scopeRegister.isLocal());
 
-    bool didCloneSymbolTable = false;
-    
     ASSERT(m_source);
     setNumParameters(unlinkedCodeBlock->numParameters());
 
@@ -1767,25 +1765,26 @@
         if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type))
             m_constantRegisters[registerIndex].set(*m_vm, ownerExecutable, m_globalObject->jsCellForLinkTimeConstant(type));
     }
-    
-    if (SymbolTable* symbolTable = unlinkedCodeBlock->symbolTable()) {
-        if (m_vm->typeProfiler()) {
-            ConcurrentJITLocker locker(symbolTable->m_lock);
-            symbolTable->prepareForTypeProfiling(locker);
+
+    HashSet<int, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> clonedConstantSymbolTables;
+    m_symbolTableConstantIndex = unlinkedCodeBlock->symbolTableConstantIndex();
+    {
+        HashSet<SymbolTable*> clonedSymbolTables;
+        for (unsigned i = 0; i < m_constantRegisters.size(); i++) {
+            if (m_constantRegisters[i].get().isEmpty())
+                continue;
+            if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(m_constantRegisters[i].get())) {
+                RELEASE_ASSERT(clonedSymbolTables.add(symbolTable).isNewEntry);
+                if (m_vm->typeProfiler()) {
+                    ConcurrentJITLocker locker(symbolTable->m_lock);
+                    symbolTable->prepareForTypeProfiling(locker);
+                }
+                m_constantRegisters[i].set(*m_vm, ownerExecutable, symbolTable->cloneScopePart(*m_vm));
+                clonedConstantSymbolTables.add(i + FirstConstantRegisterIndex);
+            }
         }
+    }
 
-        SymbolTable* newTable;
-        if (codeType() == FunctionCode && symbolTable->scopeSize()) {
-            newTable = symbolTable->cloneScopePart(*m_vm);
-            didCloneSymbolTable = true;
-        } else
-            newTable = symbolTable;
-
-        m_symbolTableConstantIndex = unlinkedCodeBlock->symbolTableConstantIndex();
-        replaceConstant(m_symbolTableConstantIndex, newTable);
-    } else 
-        m_symbolTableConstantIndex = 0;
-
     m_functionDecls.resizeToFit(unlinkedCodeBlock->numberOfFunctionDecls());
     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
@@ -1868,8 +1867,6 @@
 
     Vector<Instruction, 0, UnsafeVectorOverflow> instructions(instructionCount);
 
-    HashSet<int, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> clonedConstantSymbolTables;
-
     for (unsigned i = 0; !instructionReader.atEnd(); ) {
         const UnlinkedInstruction* pc = instructionReader.next();
 
@@ -1962,6 +1959,12 @@
         case op_get_array_length:
             CRASH();
 
+        case op_create_lexical_environment: {
+            int symbolTableIndex = pc[3].u.operand;
+            RELEASE_ASSERT(clonedConstantSymbolTables.contains(symbolTableIndex));
+            break;
+        }
+
         case op_resolve_scope: {
             const Identifier& ident = identifier(pc[3].u.operand);
             ResolveType type = static_cast<ResolveType>(pc[4].u.operand);
@@ -2013,29 +2016,8 @@
             if (modeAndType.type() == LocalClosureVar) {
                 // Only do watching if the property we're putting to is not anonymous.
                 if (static_cast<unsigned>(pc[2].u.operand) != UINT_MAX) {
-                    // Different create_lexical_environment instructions may refer to the same symbol table. 
-                    // This is used for ES6's 'for' loops each having a separate activation. We will emit two 
-                    // create_lexical_environment instructions for a given loop to implement this feature, 
-                    // but both instructions should rely on the same underlying symbol table so that the 
-                    // loop's scope isn't mistakenly inferred as a singleton scope.
                     int symbolTableIndex = pc[5].u.operand;
-                    auto addResult = clonedConstantSymbolTables.add(symbolTableIndex);
-                    if (addResult.isNewEntry) {
-                        SymbolTable* unlinkedTable = jsCast<SymbolTable*>(getConstant(symbolTableIndex));
-                        SymbolTable* linkedTable;
-                        if (unlinkedTable->correspondsToLexicalScope()) {
-                            RELEASE_ASSERT(unlinkedTable->scopeSize());
-                            linkedTable = unlinkedTable->cloneScopePart(*m_vm);
-                        } else {
-                            // There is only one SymbolTable per function that does not correspond
-                            // to a lexical scope and that is the function's var symbol table.
-                            // We've already cloned that.
-                            linkedTable = symbolTable();
-                            if (linkedTable->scopeSize())
-                                RELEASE_ASSERT(didCloneSymbolTable);
-                        }
-                        replaceConstant(symbolTableIndex, linkedTable);
-                    }
+                    RELEASE_ASSERT(clonedConstantSymbolTables.contains(symbolTableIndex));
                     SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(symbolTableIndex));
                     const Identifier& ident = identifier(pc[2].u.operand);
                     ConcurrentJITLocker locker(symbolTable->m_lock);
@@ -2106,6 +2088,10 @@
             }
             case ProfileTypeBytecodePutToLocalScope:
             case ProfileTypeBytecodeGetFromLocalScope: {
+                if (!m_symbolTableConstantIndex) {
+                    globalVariableID = TypeProfilerNoGlobalIDExists;
+                    break;
+                }
                 const Identifier& ident = identifier(pc[4].u.operand);
                 symbolTable = this->symbolTable();
                 ConcurrentJITLocker locker(symbolTable->m_lock);
@@ -2118,6 +2104,10 @@
             }
 
             case ProfileTypeBytecodeHasGlobalID: {
+                if (!m_symbolTableConstantIndex) {
+                    globalVariableID = TypeProfilerNoGlobalIDExists;
+                    break;
+                }
                 symbolTable = this->symbolTable();
                 ConcurrentJITLocker locker(symbolTable->m_lock);
                 globalVariableID = symbolTable->uniqueIDForOffset(locker, VarOffset(profileRegister), *vm());
@@ -3839,13 +3829,19 @@
 
 String CodeBlock::nameForRegister(VirtualRegister virtualRegister)
 {
-    ConcurrentJITLocker locker(symbolTable()->m_lock);
-    SymbolTable::Map::iterator end = symbolTable()->end(locker);
-    for (SymbolTable::Map::iterator ptr = symbolTable()->begin(locker); ptr != end; ++ptr) {
-        if (ptr->value.varOffset() == VarOffset(virtualRegister)) {
-            // FIXME: This won't work from the compilation thread.
-            // https://bugs.webkit.org/show_bug.cgi?id=115300
-            return ptr->key.get();
+    for (unsigned i = 0; i < m_constantRegisters.size(); i++) {
+        if (m_constantRegisters[i].get().isEmpty())
+            continue;
+        if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(m_constantRegisters[i].get())) {
+            ConcurrentJITLocker locker(symbolTable->m_lock);
+            auto end = symbolTable->end(locker);
+            for (auto ptr = symbolTable->begin(locker); ptr != end; ++ptr) {
+                if (ptr->value.varOffset() == VarOffset(virtualRegister)) {
+                    // FIXME: This won't work from the compilation thread.
+                    // https://bugs.webkit.org/show_bug.cgi?id=115300
+                    return ptr->key.get();
+                }
+            }
         }
     }
     if (virtualRegister == thisRegister())

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (187032 => 187033)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h	2015-07-20 21:16:41 UTC (rev 187033)
@@ -664,8 +664,6 @@
     StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
     StringJumpTable& stringSwitchJumpTable(int tableIndex) { RELEASE_ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
 
-    SymbolTable* symbolTable() const { RELEASE_ASSERT(m_symbolTableConstantIndex); return jsCast<SymbolTable*>(getConstant(m_symbolTableConstantIndex)); }
-
     EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
 
     enum ShrinkMode {
@@ -918,6 +916,15 @@
 private:
     friend class CodeBlockSet;
     
+    SymbolTable* symbolTable() const 
+    { 
+        // FIXME: Get rid of this function once the type profiler has a notion of what
+        // symbol table it's reading from.
+        // https://bugs.webkit.org/show_bug.cgi?id=145438
+        RELEASE_ASSERT(m_symbolTableConstantIndex); 
+        return jsCast<SymbolTable*>(getConstant(m_symbolTableConstantIndex));
+    }
+
     CodeBlock* specialOSREntryBlockOrNull();
     
     void noticeIncomingCall(ExecState* callerFrame);

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (187032 => 187033)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2015-07-20 21:16:41 UTC (rev 187033)
@@ -116,8 +116,6 @@
     visitor.append(&thisObject->m_codeBlockForCall);
     visitor.append(&thisObject->m_codeBlockForConstruct);
     visitor.append(&thisObject->m_nameValue);
-    visitor.append(&thisObject->m_symbolTableForCall);
-    visitor.append(&thisObject->m_symbolTableForConstruct);
 }
 
 FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& ownerSource, int overrideLineNumber)
@@ -209,11 +207,9 @@
     switch (specializationKind) {
     case CodeForCall:
         m_codeBlockForCall.set(vm, this, result);
-        m_symbolTableForCall.set(vm, this, result->symbolTable());
         break;
     case CodeForConstruct:
         m_codeBlockForConstruct.set(vm, this, result);
-        m_symbolTableForConstruct.set(vm, this, result->symbolTable());
         break;
     }
     return result;

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (187032 => 187033)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2015-07-20 21:16:41 UTC (rev 187033)
@@ -118,10 +118,6 @@
     const Identifier& name() const { return m_name; }
     const Identifier& inferredName() const { return m_inferredName; }
     JSString* nameValue() const { return m_nameValue.get(); }
-    SymbolTable* symbolTable(CodeSpecializationKind kind)
-    {
-        return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
-    }
     unsigned parameterCount() const { return m_parameterCount; };
     FunctionParseMode parseMode() const { return m_parseMode; };
     bool isInStrictContext() const { return m_isInStrictContext; }
@@ -149,8 +145,6 @@
 
     void clearCodeForRecompilation()
     {
-        m_symbolTableForCall.clear();
-        m_symbolTableForConstruct.clear();
         m_codeBlockForCall.clear();
         m_codeBlockForConstruct.clear();
     }
@@ -179,8 +173,6 @@
     Identifier m_name;
     Identifier m_inferredName;
     WriteBarrier<JSString> m_nameValue;
-    WriteBarrier<SymbolTable> m_symbolTableForCall;
-    WriteBarrier<SymbolTable> m_symbolTableForConstruct;
     RefPtr<SourceProvider> m_sourceOverride;
     VariableEnvironment m_parentScopeTDZVariables;
     unsigned m_firstLineOffset;
@@ -423,8 +415,6 @@
     void addExceptionHandler(const UnlinkedHandlerInfo& handler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(handler); }
     UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
 
-    SymbolTable* symbolTable() const { return m_symbolTable.get(); }
-    void setSymbolTable(SymbolTable* table) { m_symbolTable.set(*m_vm, this, table); }
     void setSymbolTableConstantIndex(int index) { m_symbolTableConstantIndex = index; }
     int symbolTableConstantIndex() const { return m_symbolTableConstantIndex; }
 
@@ -570,7 +560,7 @@
     FunctionExpressionVector m_functionExprs;
 
     WriteBarrier<SymbolTable> m_symbolTable;
-    int m_symbolTableConstantIndex;
+    int m_symbolTableConstantIndex { 0 };
 
     Vector<unsigned> m_propertyAccessInstructions;
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (187032 => 187033)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2015-07-20 21:16:41 UTC (rev 187033)
@@ -155,9 +155,6 @@
 
     m_codeBlock->shrinkToFit();
 
-    if (m_codeBlock->symbolTable() && !m_codeBlock->vm()->typeProfiler())
-        m_codeBlock->setSymbolTable(m_codeBlock->symbolTable()->cloneScopePart(*m_codeBlock->vm()));
-
     if (m_expressionTooDeep)
         return ParserError(ParserError::OutOfMemory);
     return ParserError(ParserError::ErrorNone);
@@ -199,12 +196,12 @@
 BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, UnlinkedFunctionCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode, const VariableEnvironment* parentScopeTDZVariables)
     : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
     , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
-    , m_symbolTable(codeBlock->symbolTable())
     , m_scopeNode(functionNode)
     , m_codeBlock(vm, codeBlock)
     , m_codeType(FunctionCode)
     , m_vm(&vm)
     , m_isBuiltinFunction(codeBlock->isBuiltinFunction())
+    , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
 {
     for (auto& constantRegister : m_linkTimeConstantRegisters)
         constantRegister = nullptr;
@@ -212,7 +209,11 @@
     if (m_isBuiltinFunction)
         m_shouldEmitDebugHooks = false;
     
-    m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
+    SymbolTable* functionSymbolTable = SymbolTable::create(*m_vm);
+    functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval);
+    int symbolTableConstantIndex = addConstantValue(functionSymbolTable)->index();
+    m_codeBlock->setSymbolTableConstantIndex(symbolTableConstantIndex);
+
     Vector<Identifier> boundParameterProperties;
     FunctionParameters& parameters = *functionNode->parameters();
     for (size_t i = 0; i < parameters.size(); i++) {
@@ -262,8 +263,6 @@
         emitPushFunctionNameScope(m_scopeRegister, functionNode->ident(), &m_calleeRegister, ReadOnly | DontDelete);
     }
     
-    int symbolTableConstantIndex = addConstantValue(m_symbolTable)->index();
-    m_codeBlock->setSymbolTableConstantIndex(symbolTableConstantIndex);
     if (shouldCaptureSomeOfTheThings) {
         m_lexicalEnvironmentRegister = addVar();
         m_codeBlock->setActivationRegister(m_lexicalEnvironmentRegister->virtualRegister());
@@ -327,15 +326,15 @@
         // activation.
         
         if (capturesAnyArgumentByName) {
-            m_symbolTable->setArgumentsLength(vm, parameters.size());
+            functionSymbolTable->setArgumentsLength(vm, parameters.size());
             
             // For each parameter, we have two possibilities:
             // Either it's a binding node with no function overlap, in which case it gets a name
             // in the symbol table - or it just gets space reserved in the symbol table. Either
             // way we lift the value into the scope.
             for (unsigned i = 0; i < parameters.size(); ++i) {
-                ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
-                m_symbolTable->setArgumentOffset(vm, i, offset);
+                ScopeOffset offset = functionSymbolTable->takeNextScopeOffset();
+                functionSymbolTable->setArgumentOffset(vm, i, offset);
                 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i))) {
                     VarOffset varOffset(offset);
                     SymbolTableEntry entry(varOffset);
@@ -344,7 +343,7 @@
                     // parameters when "arguments" is in play is unlikely to be super profitable.
                     // So, we just disable it.
                     entry.disableWatching();
-                    m_symbolTable->set(name, entry);
+                    functionSymbolTable->set(name, entry);
                 }
                 emitOpcode(op_put_to_scope);
                 instructions().append(m_lexicalEnvironmentRegister->index());
@@ -365,7 +364,7 @@
             // that the symbol table knows that this is happening.
             for (unsigned i = 0; i < parameters.size(); ++i) {
                 if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i)))
-                    m_symbolTable->set(name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
+                    functionSymbolTable->set(name, SymbolTableEntry(VarOffset(DirectArgumentsOffset(i))));
             }
             
             emitOpcode(op_create_direct_arguments);
@@ -382,14 +381,14 @@
             if (!captures(name)) {
                 // This is the easy case - just tell the symbol table about the argument. It will
                 // be accessed directly.
-                m_symbolTable->set(name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
+                functionSymbolTable->set(name, SymbolTableEntry(VarOffset(virtualRegisterForArgument(1 + i))));
                 continue;
             }
             
-            ScopeOffset offset = m_symbolTable->takeNextScopeOffset();
+            ScopeOffset offset = functionSymbolTable->takeNextScopeOffset();
             const Identifier& ident =
                 static_cast<const BindingNode*>(parameters.at(i))->boundProperty();
-            m_symbolTable->set(name, SymbolTableEntry(VarOffset(offset)));
+            functionSymbolTable->set(name, SymbolTableEntry(VarOffset(offset)));
             
             emitOpcode(op_put_to_scope);
             instructions().append(m_lexicalEnvironmentRegister->index());
@@ -409,10 +408,10 @@
     
     // Now declare all variables.
     for (const Identifier& ident : boundParameterProperties)
-        createVariable(ident, varKind(ident.impl()));
+        createVariable(ident, varKind(ident.impl()), functionSymbolTable);
     for (FunctionBodyNode* function : functionNode->functionStack()) {
         const Identifier& ident = function->ident();
-        createVariable(ident, varKind(ident.impl()));
+        createVariable(ident, varKind(ident.impl()), functionSymbolTable);
         m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
     }
     for (auto& entry : functionNode->varDeclarations()) {
@@ -420,7 +419,7 @@
         if (!entry.value.isVar()) // This is either a parameter or callee.
             continue;
         // Variables named "arguments" are never const.
-        createVariable(Identifier::fromUid(m_vm, entry.key.get()), varKind(entry.key.get()), IgnoreExisting);
+        createVariable(Identifier::fromUid(m_vm, entry.key.get()), varKind(entry.key.get()), functionSymbolTable, IgnoreExisting);
     }
     
     // There are some variables that need to be preinitialized to something other than Undefined:
@@ -449,13 +448,13 @@
     // to do this because we can just check if it's in the symbol table.
     if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())
         && !functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode())
-        && m_symbolTable->get(functionNode->ident().impl()).isNull()) {
+        && functionSymbolTable->get(functionNode->ident().impl()).isNull()) {
         if (captures(functionNode->ident().impl())) {
             ScopeOffset offset;
             {
-                ConcurrentJITLocker locker(m_symbolTable->m_lock);
-                offset = m_symbolTable->takeNextScopeOffset(locker);
-                m_symbolTable->add(
+                ConcurrentJITLocker locker(functionSymbolTable->m_lock);
+                offset = functionSymbolTable->takeNextScopeOffset(locker);
+                functionSymbolTable->add(
                     locker, functionNode->ident().impl(),
                     SymbolTableEntry(VarOffset(offset), ReadOnly));
             }
@@ -468,7 +467,7 @@
             instructions().append(symbolTableConstantIndex);
             instructions().append(offset.offset());
         } else {
-            m_symbolTable->add(
+            functionSymbolTable->add(
                 functionNode->ident().impl(),
                 SymbolTableEntry(VarOffset(m_calleeRegister.virtualRegister()), ReadOnly));
         }
@@ -496,7 +495,7 @@
         
         if (!haveParameterNamedArguments) {
             createVariable(
-                propertyNames().arguments, varKind(propertyNames().arguments.impl()));
+                propertyNames().arguments, varKind(propertyNames().arguments.impl()), functionSymbolTable);
             m_needToInitializeArguments = true;
         }
     }
@@ -520,27 +519,24 @@
 
     if (m_lexicalEnvironmentRegister)
         pushScopedControlFlowContext();
-    m_symbolTableStack.append(SymbolTableStackEntry{ Strong<SymbolTable>(*m_vm, m_symbolTable), m_lexicalEnvironmentRegister, false, symbolTableConstantIndex });
+    m_symbolTableStack.append(SymbolTableStackEntry{ Strong<SymbolTable>(*m_vm, functionSymbolTable), m_lexicalEnvironmentRegister, false, symbolTableConstantIndex });
     m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false));
 }
 
 BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode, const VariableEnvironment* parentScopeTDZVariables)
     : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn)
     , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn)
-    , m_symbolTable(codeBlock->symbolTable())
     , m_scopeNode(evalNode)
     , m_codeBlock(vm, codeBlock)
     , m_thisRegister(CallFrame::thisArgumentOffset())
     , m_codeType(EvalCode)
     , m_vm(&vm)
+    , m_usesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode())
 {
     for (auto& constantRegister : m_linkTimeConstantRegisters)
         constantRegister = nullptr;
 
-    m_symbolTable->setUsesNonStrictEval(codeBlock->usesEval() && !codeBlock->isStrictMode());
     m_codeBlock->setNumParameters(1);
-    int symbolTableConstantIndex = addConstantValue(m_symbolTable)->index();
-    m_codeBlock->setSymbolTableConstantIndex(symbolTableConstantIndex);
 
     emitOpcode(op_enter);
 
@@ -1305,7 +1301,7 @@
         newScope = newBlockScopeVariable();
         newScope->ref();
 
-        RegisterID* constantSymbolTable = addConstantValue(symbolTable->cloneScopePart(*m_vm));
+        RegisterID* constantSymbolTable = addConstantValue(!m_codeBlock->vm()->typeProfiler() ? symbolTable->cloneScopePart(*m_vm) : symbolTable.get());
         symbolTableConstantIndex = constantSymbolTable->index();
         if (constantSymbolTableResult)
             *constantSymbolTableResult = constantSymbolTable;
@@ -1504,11 +1500,11 @@
 }
 
 void BytecodeGenerator::createVariable(
-    const Identifier& property, VarKind varKind, ExistingVariableMode existingVariableMode)
+    const Identifier& property, VarKind varKind, SymbolTable* symbolTable, ExistingVariableMode existingVariableMode)
 {
     ASSERT(property != propertyNames().thisIdentifier);
-    ConcurrentJITLocker locker(symbolTable().m_lock);
-    SymbolTableEntry entry = symbolTable().get(locker, property.impl());
+    ConcurrentJITLocker locker(symbolTable->m_lock);
+    SymbolTableEntry entry = symbolTable->get(locker, property.impl());
     
     if (!entry.isNull()) {
         if (existingVariableMode == IgnoreExisting)
@@ -1532,13 +1528,13 @@
     
     VarOffset varOffset;
     if (varKind == VarKind::Scope)
-        varOffset = VarOffset(symbolTable().takeNextScopeOffset(locker));
+        varOffset = VarOffset(symbolTable->takeNextScopeOffset(locker));
     else {
         ASSERT(varKind == VarKind::Stack);
         varOffset = VarOffset(virtualRegisterForLocal(m_calleeRegisters.size()));
     }
     SymbolTableEntry newEntry(varOffset, 0);
-    symbolTable().add(locker, property.impl(), newEntry);
+    symbolTable->add(locker, property.impl(), newEntry);
     
     if (varKind == VarKind::Stack) {
         RegisterID* local = addVar();
@@ -1565,7 +1561,7 @@
             return Dynamic;
     }
 
-    if (m_symbolTable && m_symbolTable->usesNonStrictEval())
+    if (m_usesNonStrictEval)
         return GlobalPropertyWithVarInjectionChecks;
     return GlobalProperty;
 }
@@ -1606,8 +1602,6 @@
     case VarKind::Invalid:
         // Indicates non-local resolution.
         
-        ASSERT(!m_symbolTable || !m_symbolTable->contains(variable.ident().impl()) || resolveType() == Dynamic);
-        
         m_codeBlock->addPropertyAccessInstruction(instructions().size());
         
         // resolve_scope dst, id, ResolveType, depth

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (187032 => 187033)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2015-07-20 21:16:41 UTC (rev 187033)
@@ -292,7 +292,7 @@
         Variable variable(const Identifier&);
         
         enum ExistingVariableMode { VerifyExisting, IgnoreExisting };
-        void createVariable(const Identifier&, VarKind, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
+        void createVariable(const Identifier&, VarKind, SymbolTable*, ExistingVariableMode = VerifyExisting); // Creates the variable, or asserts that the already-created variable is sufficiently compatible.
         
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
@@ -715,8 +715,6 @@
 
         Vector<UnlinkedInstruction, 0, UnsafeVectorOverflow>& instructions() { return m_instructions; }
 
-        SymbolTable& symbolTable() { return *m_symbolTable; }
-
         RegisterID* emitThrowExpressionTooDeepException();
 
     private:
@@ -725,7 +723,6 @@
         bool m_shouldEmitDebugHooks;
         bool m_shouldEmitProfileHooks;
 
-        SymbolTable* m_symbolTable { nullptr };
         struct SymbolTableStackEntry {
             Strong<SymbolTable> m_symbolTable;
             RegisterID* m_scope;
@@ -803,6 +800,7 @@
         bool m_usesExceptions { false };
         bool m_expressionTooDeep { false };
         bool m_isBuiltinFunction { false };
+        bool m_usesNonStrictEval { false };
     };
 
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (187032 => 187033)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2015-07-20 21:16:41 UTC (rev 187033)
@@ -365,16 +365,6 @@
         return baselineCodeBlockForOriginAndBaselineCodeBlock(codeOrigin, m_profiledBlock);
     }
     
-    SymbolTable* symbolTableFor(InlineCallFrame* inlineCallFrame)
-    {
-        return baselineCodeBlockFor(inlineCallFrame)->symbolTable();
-    }
-    
-    SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
-    {
-        return symbolTableFor(codeOrigin.inlineCallFrame);
-    }
-    
     bool isStrictModeFor(CodeOrigin codeOrigin)
     {
         if (!codeOrigin.inlineCallFrame)

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (187032 => 187033)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2015-07-20 21:16:41 UTC (rev 187033)
@@ -886,11 +886,6 @@
         return m_baselineCodeBlock;
     }
     
-    SymbolTable* symbolTableFor(const CodeOrigin& codeOrigin)
-    {
-        return baselineCodeBlockFor(codeOrigin)->symbolTable();
-    }
-
     static VirtualRegister argumentsStart(InlineCallFrame* inlineCallFrame)
     {
         if (!inlineCallFrame)

Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (187032 => 187033)


--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2015-07-20 21:16:41 UTC (rev 187033)
@@ -215,7 +215,7 @@
 {
     BEGIN();
     JSLexicalEnvironment* scope = jsCast<JSLexicalEnvironment*>(OP(2).jsValue());
-    ScopedArgumentsTable* table = exec->codeBlock()->symbolTable()->arguments();
+    ScopedArgumentsTable* table = scope->symbolTable()->arguments();
     RETURN(ScopedArguments::createByCopying(exec, table, scope));
 }
 

Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (187032 => 187033)


--- trunk/Source/_javascript_Core/runtime/Executable.cpp	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp	2015-07-20 21:16:41 UTC (rev 187033)
@@ -572,11 +572,6 @@
     visitor.append(&thisObject->m_singletonFunction);
 }
 
-SymbolTable* FunctionExecutable::symbolTable(CodeSpecializationKind kind)
-{
-    return codeBlockFor(kind)->symbolTable();
-}
-
 void FunctionExecutable::clearUnlinkedCodeForRecompilation()
 {
     m_unlinkedExecutable->clearCodeForRecompilation();

Modified: trunk/Source/_javascript_Core/runtime/Executable.h (187032 => 187033)


--- trunk/Source/_javascript_Core/runtime/Executable.h	2015-07-20 20:45:42 UTC (rev 187032)
+++ trunk/Source/_javascript_Core/runtime/Executable.h	2015-07-20 21:16:41 UTC (rev 187033)
@@ -635,7 +635,6 @@
     const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
     JSString* nameValue() const { return m_unlinkedExecutable->nameValue(); }
     size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
-    SymbolTable* symbolTable(CodeSpecializationKind);
 
     void clearUnlinkedCodeForRecompilation();
     static void visitChildren(JSCell*, SlotVisitor&);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to