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&);