Commit 47e224a6 authored by ggaren@apple.com's avatar ggaren@apple.com

Don't use malloc / destructors for activation objects

https://bugs.webkit.org/show_bug.cgi?id=94897

Reviewed by Oliver Hunt.

65% faster on v8-real-earley.

Lots of boilerplate here, but the jist is this:

(1) Use CopiedSpace instead of malloc to allocate the activation's
backing store.

(2) Use MarkedSpace instead of ref-counting to allocate the symbol table.

(3) ==> No more destructor.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::stronglyVisitStrongReferences):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::symbolTable):
(CodeBlock):
(JSC::GlobalCodeBlock::GlobalCodeBlock):
(JSC::FunctionCodeBlock::FunctionCodeBlock):
(FunctionCodeBlock): SymbolTable is a GC object now, so it gets a write
barrier and visit calls instead of ref-counting. I changed all CodeBlocks
to use shared symbol tables because the distinction between shared and
unshared hurt my head.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::resolve):
(JSC::BytecodeGenerator::resolveConstDecl):
(JSC::BytecodeGenerator::emitPutStaticVar):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile): Sometimes, a period just wants
to be an arrow. And then C++ is there to accommodate.

* jit/JITDriver.h:
(JSC::jitCompileFunctionIfAppropriate):
* runtime/Arguments.h:
(ArgumentsData):
(JSC::Arguments::setRegisters):
(Arguments):
(JSC::Arguments::argument):
(JSC::Arguments::finishCreation):
* runtime/Executable.cpp:
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
(JSC::FunctionExecutable::visitChildren):
* runtime/Executable.h:
(JSC::FunctionExecutable::symbolTable):
(FunctionExecutable):
* runtime/ExecutionHarness.h:
(JSC::prepareFunctionForExecution): I changed from WriteBarrier to
WriteBarrierBase so activations could reuse StorageBarrier and PropertyStorage.

* runtime/JSActivation.cpp:
(JSC::JSActivation::JSActivation):
(JSC::JSActivation::finishCreation): Allocate the symbol table here,
after we're fully constructed, to avoid GC during initialization.

(JSC::JSActivation::visitChildren):
(JSC::JSActivation::symbolTableGet):
(JSC::JSActivation::symbolTablePut):
(JSC::JSActivation::getOwnPropertyNames):
(JSC::JSActivation::symbolTablePutWithAttributes):
* runtime/JSActivation.h:
(JSC::JSActivation::create):
(JSActivation):
(JSC::JSActivation::registerOffset):
(JSC):
(JSC::JSActivation::registerArraySize):
(JSC::JSActivation::registerArraySizeInBytes):
(JSC::JSActivation::tearOff): Tear-off zero-initializes all uncopied
registers. This makes it safe to copyAndAppend the full buffer in
visitChildren, without any extra checks.

* runtime/JSCell.h:
(JSCell): Moved a shared default set of flags into this base class, so
I could use it in a few places.

* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalData.h:
(JSGlobalData): New structure for symbol tables.

* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::addStaticGlobals):
* runtime/JSGlobalObject.h:
(JSGlobalObject):
(JSC::JSGlobalObject::symbolTableHasProperty): We don't need an inline
symbol table -- JSSymbolTableObject will GC allocate one for us.

* runtime/JSObject.h:
(JSObject):
* runtime/JSSegmentedVariableObject.h:
(JSC::JSSegmentedVariableObject::JSSegmentedVariableObject):
* runtime/JSStaticScopeObject.cpp:
(JSC):
(JSC::JSStaticScopeObject::visitChildren): NULL check our register store
because finishCreation allocates an object now, so we may get marked
before we've assigned to our register store.

* runtime/JSStaticScopeObject.h:
(JSC::JSStaticScopeObject::finishCreation):
(JSC::JSStaticScopeObject::JSStaticScopeObject):
(JSStaticScopeObject): No more destructor for this object, either, since
it no longer embeds a hash table.

* runtime/JSSymbolTableObject.cpp:
(JSC::JSSymbolTableObject::visitChildren):
(JSC::JSSymbolTableObject::deleteProperty):
(JSC::JSSymbolTableObject::getOwnPropertyNames):
* runtime/JSSymbolTableObject.h:
(JSC::JSSymbolTableObject::symbolTable):
(JSSymbolTableObject):
(JSC::JSSymbolTableObject::JSSymbolTableObject):
(JSC::JSSymbolTableObject::finishCreation):
(JSC::symbolTableGet):
(JSC::symbolTablePut):
(JSC::symbolTablePutWithAttributes): SymbolTableObject allocates a symbol
table automatically if one isn't provided. (Activations provide their
own, which they get from compiled code.)

* runtime/JSVariableObject.cpp:
(JSC):
* runtime/JSVariableObject.h:
(JSC::JSVariableObject::registerAt):
(JSC::JSVariableObject::addressOfRegisters):
(JSVariableObject):
(JSC::JSVariableObject::JSVariableObject):
(JSC::JSVariableObject::finishCreation): Removed a bunch of obsolete code.
Activations manage their registers directly now.

* runtime/StorageBarrier.h:
(StorageBarrier):
(JSC::StorageBarrier::operator!):

* runtime/SymbolTable.cpp:
(JSC):
(JSC::SharedSymbolTable::destroy):
* runtime/SymbolTable.h:
(JSC::SharedSymbolTable::create):
(SharedSymbolTable):
(JSC::SharedSymbolTable::createStructure):
(JSC::SharedSymbolTable::SharedSymbolTable): Boilerplat code to
make shared symbol table GC-allocated.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@126695 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f9d4dadf
2012-08-25 Geoffrey Garen <ggaren@apple.com>
Don't use malloc / destructors for activation objects
https://bugs.webkit.org/show_bug.cgi?id=94897
Reviewed by Oliver Hunt.
65% faster on v8-real-earley.
Lots of boilerplate here, but the jist is this:
(1) Use CopiedSpace instead of malloc to allocate the activation's
backing store.
(2) Use MarkedSpace instead of ref-counting to allocate the symbol table.
(3) ==> No more destructor.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::stronglyVisitStrongReferences):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::symbolTable):
(CodeBlock):
(JSC::GlobalCodeBlock::GlobalCodeBlock):
(JSC::FunctionCodeBlock::FunctionCodeBlock):
(FunctionCodeBlock): SymbolTable is a GC object now, so it gets a write
barrier and visit calls instead of ref-counting. I changed all CodeBlocks
to use shared symbol tables because the distinction between shared and
unshared hurt my head.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::resolve):
(JSC::BytecodeGenerator::resolveConstDecl):
(JSC::BytecodeGenerator::emitPutStaticVar):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile): Sometimes, a period just wants
to be an arrow. And then C++ is there to accommodate.
* jit/JITDriver.h:
(JSC::jitCompileFunctionIfAppropriate):
* runtime/Arguments.h:
(ArgumentsData):
(JSC::Arguments::setRegisters):
(Arguments):
(JSC::Arguments::argument):
(JSC::Arguments::finishCreation):
* runtime/Executable.cpp:
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
(JSC::FunctionExecutable::visitChildren):
* runtime/Executable.h:
(JSC::FunctionExecutable::symbolTable):
(FunctionExecutable):
* runtime/ExecutionHarness.h:
(JSC::prepareFunctionForExecution): I changed from WriteBarrier to
WriteBarrierBase so activations could reuse StorageBarrier and PropertyStorage.
* runtime/JSActivation.cpp:
(JSC::JSActivation::JSActivation):
(JSC::JSActivation::finishCreation): Allocate the symbol table here,
after we're fully constructed, to avoid GC during initialization.
(JSC::JSActivation::visitChildren):
(JSC::JSActivation::symbolTableGet):
(JSC::JSActivation::symbolTablePut):
(JSC::JSActivation::getOwnPropertyNames):
(JSC::JSActivation::symbolTablePutWithAttributes):
* runtime/JSActivation.h:
(JSC::JSActivation::create):
(JSActivation):
(JSC::JSActivation::registerOffset):
(JSC):
(JSC::JSActivation::registerArraySize):
(JSC::JSActivation::registerArraySizeInBytes):
(JSC::JSActivation::tearOff): Tear-off zero-initializes all uncopied
registers. This makes it safe to copyAndAppend the full buffer in
visitChildren, without any extra checks.
* runtime/JSCell.h:
(JSCell): Moved a shared default set of flags into this base class, so
I could use it in a few places.
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalData.h:
(JSGlobalData): New structure for symbol tables.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::addStaticGlobals):
* runtime/JSGlobalObject.h:
(JSGlobalObject):
(JSC::JSGlobalObject::symbolTableHasProperty): We don't need an inline
symbol table -- JSSymbolTableObject will GC allocate one for us.
* runtime/JSObject.h:
(JSObject):
* runtime/JSSegmentedVariableObject.h:
(JSC::JSSegmentedVariableObject::JSSegmentedVariableObject):
* runtime/JSStaticScopeObject.cpp:
(JSC):
(JSC::JSStaticScopeObject::visitChildren): NULL check our register store
because finishCreation allocates an object now, so we may get marked
before we've assigned to our register store.
* runtime/JSStaticScopeObject.h:
(JSC::JSStaticScopeObject::finishCreation):
(JSC::JSStaticScopeObject::JSStaticScopeObject):
(JSStaticScopeObject): No more destructor for this object, either, since
it no longer embeds a hash table.
* runtime/JSSymbolTableObject.cpp:
(JSC::JSSymbolTableObject::visitChildren):
(JSC::JSSymbolTableObject::deleteProperty):
(JSC::JSSymbolTableObject::getOwnPropertyNames):
* runtime/JSSymbolTableObject.h:
(JSC::JSSymbolTableObject::symbolTable):
(JSSymbolTableObject):
(JSC::JSSymbolTableObject::JSSymbolTableObject):
(JSC::JSSymbolTableObject::finishCreation):
(JSC::symbolTableGet):
(JSC::symbolTablePut):
(JSC::symbolTablePutWithAttributes): SymbolTableObject allocates a symbol
table automatically if one isn't provided. (Activations provide their
own, which they get from compiled code.)
* runtime/JSVariableObject.cpp:
(JSC):
* runtime/JSVariableObject.h:
(JSC::JSVariableObject::registerAt):
(JSC::JSVariableObject::addressOfRegisters):
(JSVariableObject):
(JSC::JSVariableObject::JSVariableObject):
(JSC::JSVariableObject::finishCreation): Removed a bunch of obsolete code.
Activations manage their registers directly now.
* runtime/StorageBarrier.h:
(StorageBarrier):
(JSC::StorageBarrier::operator!):
* runtime/SymbolTable.cpp:
(JSC):
(JSC::SharedSymbolTable::destroy):
* runtime/SymbolTable.h:
(JSC::SharedSymbolTable::create):
(SharedSymbolTable):
(JSC::SharedSymbolTable::createStructure):
(JSC::SharedSymbolTable::SharedSymbolTable): Boilerplat code to
make shared symbol table GC-allocated.
2012-08-25 Filip Pizlo <fpizlo@apple.com>
op_call should have ArrayProfiling for the benefit of array intrinsics
......
......@@ -1678,7 +1678,7 @@ void CodeBlock::dumpStatistics()
#endif
}
CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
: m_globalObject(other.m_globalObject)
, m_heap(other.m_heap)
, m_numCalleeRegisters(other.m_numCalleeRegisters)
......@@ -1710,7 +1710,7 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
, m_constantRegisters(other.m_constantRegisters)
, m_functionDecls(other.m_functionDecls)
, m_functionExprs(other.m_functionExprs)
, m_symbolTable(symTab)
, m_symbolTable(*other.m_globalData, other.m_ownerExecutable.get(), other.symbolTable())
, m_osrExitCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
......@@ -1744,7 +1744,7 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
}
}
CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor, PassOwnPtr<CodeBlock> alternative)
CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative)
: m_globalObject(globalObject->globalData(), ownerExecutable, globalObject)
, m_heap(&m_globalObject->globalData().heap)
, m_numCalleeRegisters(0)
......@@ -1764,7 +1764,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo
#if ENABLE(VALUE_PROFILER)
, m_executionEntryCount(0)
#endif
, m_symbolTable(symTab)
, m_symbolTable(globalObject->globalData(), ownerExecutable, SharedSymbolTable::create(globalObject->globalData()))
, m_alternative(alternative)
, m_osrExitCounter(0)
, m_optimizationDelayCounter(0)
......@@ -2222,6 +2222,7 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
{
visitor.append(&m_globalObject);
visitor.append(&m_ownerExecutable);
visitor.append(&m_symbolTable);
if (m_rareData) {
m_rareData->m_evalCodeCache.visitAggregate(visitor);
size_t regExpCount = m_rareData->m_regexps.size();
......
......@@ -118,9 +118,9 @@ namespace JSC {
public:
enum CopyParsedBlockTag { CopyParsedBlock };
protected:
CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable*);
CodeBlock(CopyParsedBlockTag, CodeBlock& other);
CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable*, bool isConstructor, PassOwnPtr<CodeBlock> alternative);
CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, bool isConstructor, PassOwnPtr<CodeBlock> alternative);
WriteBarrier<JSGlobalObject> m_globalObject;
Heap* m_heap;
......@@ -949,8 +949,7 @@ namespace JSC {
StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
SymbolTable* symbolTable() { return m_symbolTable; }
SharedSymbolTable* sharedSymbolTable() { ASSERT(m_codeType == FunctionCode); return static_cast<SharedSymbolTable*>(m_symbolTable); }
SharedSymbolTable* symbolTable() { return m_symbolTable.get(); }
EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
......@@ -1361,7 +1360,7 @@ namespace JSC {
Vector<WriteBarrier<FunctionExecutable> > m_functionDecls;
Vector<WriteBarrier<FunctionExecutable> > m_functionExprs;
SymbolTable* m_symbolTable;
WriteBarrier<SharedSymbolTable> m_symbolTable;
OwnPtr<CodeBlock> m_alternative;
......@@ -1423,18 +1422,14 @@ namespace JSC {
class GlobalCodeBlock : public CodeBlock {
protected:
GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
: CodeBlock(CopyParsedBlock, other, &m_unsharedSymbolTable)
, m_unsharedSymbolTable(other.m_unsharedSymbolTable)
: CodeBlock(CopyParsedBlock, other)
{
}
GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
: CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false, alternative)
: CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, false, alternative)
{
}
private:
SymbolTable m_unsharedSymbolTable;
};
class ProgramCodeBlock : public GlobalCodeBlock {
......@@ -1501,25 +1496,13 @@ namespace JSC {
class FunctionCodeBlock : public CodeBlock {
public:
FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
: CodeBlock(CopyParsedBlock, other, other.sharedSymbolTable())
: CodeBlock(CopyParsedBlock, other)
{
// The fact that we have to do this is yucky, but is necessary because of the
// class hierarchy issues described in the comment block for the main
// constructor, below.
sharedSymbolTable()->ref();
}
// Rather than using the usual RefCounted::create idiom for SharedSymbolTable we just use new
// 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 = nullptr)
: CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, SharedSymbolTable::create().leakRef(), isConstructor, alternative)
{
}
~FunctionCodeBlock()
: CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, isConstructor, alternative)
{
sharedSymbolTable()->deref();
}
#if ENABLE(JIT)
......
......@@ -1260,7 +1260,7 @@ ResolveResult BytecodeGenerator::resolve(const Identifier& property)
break;
}
JSSymbolTableObject* currentVariableObject = jsCast<JSSymbolTableObject*>(currentScope);
SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl());
SymbolTableEntry entry = currentVariableObject->symbolTable()->get(property.impl());
// Found the property
if (!entry.isNull()) {
......@@ -1327,7 +1327,7 @@ ResolveResult BytecodeGenerator::resolveConstDecl(const Identifier& property)
if (!currentScope->isVariableObject())
continue;
JSSymbolTableObject* currentVariableObject = jsCast<JSSymbolTableObject*>(currentScope);
SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl());
SymbolTableEntry entry = currentVariableObject->symbolTable()->get(property.impl());
if (entry.isNull())
continue;
if (++iter == end)
......@@ -1583,7 +1583,7 @@ RegisterID* BytecodeGenerator::emitPutStaticVar(const ResolveResult& resolveResu
emitOpcode(op_put_global_var_check);
instructions().append(resolveResult.registerPointer());
instructions().append(value->index());
instructions().append(jsCast<JSGlobalObject*>(resolveResult.globalObject())->symbolTable().get(identifier.impl()).addressOfIsWatched());
instructions().append(jsCast<JSGlobalObject*>(resolveResult.globalObject())->symbolTable()->get(identifier.impl()).addressOfIsWatched());
instructions().append(addConstant(identifier));
return value;
......
......@@ -2406,7 +2406,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
Identifier identifier = m_codeBlock->identifier(identifierNumber);
SymbolTableEntry entry = globalObject->symbolTable().get(identifier.impl());
SymbolTableEntry entry = globalObject->symbolTable()->get(identifier.impl());
if (!entry.couldBeWatched()) {
NodeIndex getGlobalVar = addToGraph(
GetGlobalVar,
......@@ -2459,7 +2459,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
JSGlobalObject* globalObject = codeBlock->globalObject();
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[4].u.operand];
Identifier identifier = m_codeBlock->identifier(identifierNumber);
SymbolTableEntry entry = globalObject->symbolTable().get(identifier.impl());
SymbolTableEntry entry = globalObject->symbolTable()->get(identifier.impl());
if (!entry.couldBeWatched()) {
addToGraph(
PutGlobalVar,
......
......@@ -3535,7 +3535,7 @@ void SpeculativeJIT::compile(Node& node)
JSValueOperand value(this, node.child1());
WatchpointSet* watchpointSet =
m_jit.globalObjectFor(node.codeOrigin)->symbolTable().get(
m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
identifier(node.identifierNumberForCheck())->impl()).watchpointSet();
addSlowPathGenerator(
slowPathCall(
......@@ -3563,7 +3563,7 @@ void SpeculativeJIT::compile(Node& node)
}
case GlobalVarWatchpoint: {
m_jit.globalObjectFor(node.codeOrigin)->symbolTable().get(
m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
identifier(node.identifierNumberForCheck())->impl()).addWatchpoint(
speculationWatchpoint());
......
......@@ -3518,7 +3518,7 @@ void SpeculativeJIT::compile(Node& node)
JSValueOperand value(this, node.child1());
WatchpointSet* watchpointSet =
m_jit.globalObjectFor(node.codeOrigin)->symbolTable().get(
m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
identifier(node.identifierNumberForCheck())->impl()).watchpointSet();
addSlowPathGenerator(
slowPathCall(
......@@ -3541,7 +3541,7 @@ void SpeculativeJIT::compile(Node& node)
}
case GlobalVarWatchpoint: {
m_jit.globalObjectFor(node.codeOrigin)->symbolTable().get(
m_jit.globalObjectFor(node.codeOrigin)->symbolTable()->get(
identifier(node.identifierNumberForCheck())->impl()).addWatchpoint(
speculationWatchpoint());
......
......@@ -75,7 +75,7 @@ inline bool jitCompileIfAppropriate(ExecState* exec, OwnPtr<CodeBlockType>& code
return true;
}
inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, WriteBarrier<SharedSymbolTable>& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
{
JSGlobalData& globalData = exec->globalData();
......@@ -99,7 +99,7 @@ inline bool jitCompileFunctionIfAppropriate(ExecState* exec, OwnPtr<FunctionCode
} else {
if (codeBlock->alternative()) {
codeBlock = static_pointer_cast<FunctionCodeBlock>(codeBlock->releaseAlternative());
symbolTable = codeBlock->sharedSymbolTable();
symbolTable.set(exec->globalData(), codeBlock->ownerExecutable(), codeBlock->symbolTable());
jitCode = oldJITCode;
jitCodeWithArityCheck = oldJITCodeWithArityCheck;
return false;
......
......@@ -49,7 +49,7 @@ namespace JSC {
bool overrodeCaller;
bool isStrictMode;
WriteBarrier<Unknown>* registers;
WriteBarrierBase<Unknown>* registers;
OwnArrayPtr<WriteBarrier<Unknown> > registerArray;
OwnArrayPtr<bool> deletedArguments;
......@@ -110,6 +110,7 @@ namespace JSC {
d->activation.set(globalData, this, activation);
d->registers = &activation->registerAt(0);
}
void setRegisters(WriteBarrierBase<Unknown>* registers) { d->registers = registers; }
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
......@@ -138,7 +139,7 @@ namespace JSC {
void createStrictModeCallerIfNecessary(ExecState*);
void createStrictModeCalleeIfNecessary(ExecState*);
WriteBarrier<Unknown>& argument(size_t);
WriteBarrierBase<Unknown>& argument(size_t);
void init(CallFrame*);
......@@ -165,7 +166,7 @@ namespace JSC {
{
}
inline WriteBarrier<Unknown>& Arguments::argument(size_t i)
inline WriteBarrierBase<Unknown>& Arguments::argument(size_t i)
{
return d->registers[CallFrame::argumentOffset(i)];
}
......@@ -177,7 +178,7 @@ namespace JSC {
JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
d->numArguments = callFrame->argumentCount();
d->registers = reinterpret_cast<WriteBarrier<Unknown>*>(callFrame->registers());
d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
d->callee.set(callFrame->globalData(), this, callee);
d->overrodeLength = false;
d->overrodeCallee = false;
......@@ -197,7 +198,7 @@ namespace JSC {
JSFunction* callee = inlineCallFrame->callee.get();
d->numArguments = inlineCallFrame->arguments.size() - 1;
d->registers = reinterpret_cast<WriteBarrier<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
d->callee.set(callFrame->globalData(), this, callee);
d->overrodeLength = false;
d->overrodeCallee = false;
......
......@@ -140,7 +140,6 @@ FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifie
, m_parameters(parameters)
, m_name(name)
, m_inferredName(inferredName.isNull() ? globalData.propertyNames->emptyIdentifier : inferredName)
, m_symbolTable(0)
{
}
......@@ -151,7 +150,6 @@ FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name,
, m_parameters(parameters)
, m_name(name)
, m_inferredName(inferredName.isNull() ? exec->globalData().propertyNames->emptyIdentifier : inferredName)
, m_symbolTable(0)
{
}
......@@ -349,7 +347,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
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() ? OptimizingCompilation : 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();
......@@ -526,7 +524,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
m_numParametersForCall = m_codeBlockForCall->numParameters();
ASSERT(m_numParametersForCall);
m_numCapturedVariables = m_codeBlockForCall->m_numCapturedVars;
m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
m_symbolTable.set(exec->globalData(), this, m_codeBlockForCall->symbolTable());
#if ENABLE(JIT)
if (!prepareFunctionForExecution(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForCall))
......@@ -569,7 +567,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
m_numParametersForConstruct = m_codeBlockForConstruct->numParameters();
ASSERT(m_numParametersForConstruct);
m_numCapturedVariables = m_codeBlockForConstruct->m_numCapturedVars;
m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
m_symbolTable.set(exec->globalData(), this, m_codeBlockForConstruct->symbolTable());
#if ENABLE(JIT)
if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForConstruct))
......@@ -615,6 +613,8 @@ void FunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
ScriptExecutable::visitChildren(thisObject, visitor);
if (thisObject->m_nameValue)
visitor.append(&thisObject->m_nameValue);
if (thisObject->m_symbolTable)
visitor.append(&thisObject->m_symbolTable);
if (thisObject->m_codeBlockForCall)
thisObject->m_codeBlockForCall->visitAggregate(visitor);
if (thisObject->m_codeBlockForConstruct)
......
......@@ -662,7 +662,7 @@ namespace JSC {
size_t parameterCount() const { return m_parameters->size(); } // Excluding 'this'!
unsigned capturedVariableCount() const { return m_numCapturedVariables; }
UString paramString() const;
SharedSymbolTable* symbolTable() const { return m_symbolTable; }
SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
void clearCodeIfNotCompiling();
static void visitChildren(JSCell*, SlotVisitor&);
......@@ -723,7 +723,7 @@ namespace JSC {
Identifier m_name;
Identifier m_inferredName;
WriteBarrier<JSString> m_nameValue;
SharedSymbolTable* m_symbolTable;
WriteBarrier<SharedSymbolTable> m_symbolTable;
};
inline FunctionExecutable* JSFunction::jsExecutable() const
......
......@@ -49,7 +49,7 @@ inline bool prepareForExecution(ExecState* exec, OwnPtr<CodeBlockType>& codeBloc
return jitCompileIfAppropriate(exec, codeBlock, jitCode, jitType, bytecodeIndex, JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail);
}
inline bool prepareFunctionForExecution(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, CodeSpecializationKind kind)
inline bool prepareFunctionForExecution(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, WriteBarrier<SharedSymbolTable>& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, CodeSpecializationKind kind)
{
#if ENABLE(LLINT)
if (JITCode::isBaselineCode(jitType)) {
......
......@@ -42,7 +42,8 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSActivation) };
JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
: Base(callFrame->globalData(), callFrame->globalData().activationStructure.get(), functionExecutable->symbolTable(), callFrame->registers())
: Base(callFrame->globalData(), callFrame->globalData().activationStructure.get(), callFrame->registers())
, m_registerArray(callFrame->globalData(), this, 0)
, m_numCapturedArgs(max(callFrame->argumentCount(), functionExecutable->parameterCount()))
, m_numCapturedVars(functionExecutable->capturedVariableCount())
, m_isTornOff(false)
......@@ -51,20 +52,10 @@ JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExe
{
}
void JSActivation::finishCreation(CallFrame* callFrame)
void JSActivation::finishCreation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
{
Base::finishCreation(callFrame->globalData());
Base::finishCreation(callFrame->globalData(), functionExecutable->symbolTable());
ASSERT(inherits(&s_info));
// We have to manually ref and deref the symbol table as JSVariableObject
// doesn't know about SharedSymbolTable
static_cast<SharedSymbolTable*>(m_symbolTable)->ref();
callFrame->globalData().heap.addFinalizer(this, &finalize);
}
void JSActivation::finalize(JSCell* cell)
{
static_cast<SharedSymbolTable*>(jsCast<JSActivation*>(cell)->m_symbolTable)->deref();
}
void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
......@@ -76,23 +67,23 @@ void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
Base::visitChildren(thisObject, visitor);
// No need to mark our registers if they're still in the RegisterFile.
WriteBarrier<Unknown>* registerArray = thisObject->m_registerArray.get();
PropertyStorage registerArray = thisObject->m_registerArray.get();
if (!registerArray)
return;
visitor.appendValues(registerArray, thisObject->m_numCapturedArgs);
// Skip 'this' and call frame, except for callee and scope chain.
int offset = CallFrame::offsetFor(thisObject->m_numCapturedArgs + 1);
visitor.append(registerArray + offset + RegisterFile::ScopeChain);
visitor.append(registerArray + offset + RegisterFile::Callee);
visitor.appendValues(registerArray + offset, thisObject->m_numCapturedVars);
visitor.copyAndAppend(reinterpret_cast<void**>(&registerArray), thisObject->registerArraySizeInBytes(), reinterpret_cast<JSValue*>(registerArray), thisObject->registerArraySize());
thisObject->m_registerArray.set(registerArray, StorageBarrier::Unchecked);
thisObject->m_registers = registerArray + thisObject->registerOffset();
// Update the arguments object, since it points at our buffer.
CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));
if (JSValue v = callFrame->uncheckedR(unmodifiedArgumentsRegister(thisObject->m_argumentsRegister)).jsValue())
jsCast<Arguments*>(v)->setRegisters(thisObject->m_registers);
}
inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot& slot)
{
SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
if (entry.isNull())
return false;
if (m_isTornOff && entry.getIndex() >= m_numCapturedVars)
......@@ -107,7 +98,7 @@ inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyN
JSGlobalData& globalData = exec->globalData();
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName());
SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName());
if (entry.isNull())
return false;
if (entry.isReadOnly()) {
......@@ -125,8 +116,8 @@ inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyN
void JSActivation::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
JSActivation* thisObject = jsCast<JSActivation*>(object);
SymbolTable::const_iterator end = thisObject->symbolTable().end();
for (SymbolTable::const_iterator it = thisObject->symbolTable().begin(); it != end; ++it) {
SymbolTable::const_iterator end = thisObject->symbolTable()->end();
for (SymbolTable::const_iterator it = thisObject->symbolTable()->begin(); it != end; ++it) {
if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)
continue;
if (it->second.getIndex() >= thisObject->m_numCapturedVars)
......@@ -141,8 +132,8 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData,
{
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
SymbolTable::iterator iter = symbolTable().find(propertyName.publicName());
if (iter == symbolTable().end())