Ignore:
Timestamp:
Mar 8, 2011, 3:17:32 PM (14 years ago)
Author:
[email protected]
Message:

2011-03-07 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Make CodeBlock GC write barrier safe
https://bugs.webkit.org/show_bug.cgi?id=55910

In order to make CodeBlock WriteBarrier safe it was necessary
to make it have a single GC owner, and for that reason I have
made ExecutableBase a GC allocated object. This required
updating their creation routines as well as all sites that hold
a reference to them. GC objects that held Executable's have been
converted to WriteBarriers, and all other sites now use Global<>.

As an added benefit this gets rid of JSGlobalData's list of
GlobalCodeBlocks.

Perf testing shows a 0.5% progression on v8, vs. a 0.3% regression
on SunSpider. Given none of the tests that show regressions
demonstrate a regression on their own, and sampling shows up nothing.
I suspect we're just getting one or two additional gc passes at
the end of the run.

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): (JSC::CodeBlock::CodeBlock): (JSC::EvalCodeCache::markAggregate): (JSC::CodeBlock::markAggregate):
  • bytecode/CodeBlock.h: (JSC::CodeBlock::ownerExecutable): (JSC::CodeBlock::addConstant): (JSC::CodeBlock::constantRegister): (JSC::CodeBlock::getConstant): (JSC::CodeBlock::addFunctionDecl): (JSC::CodeBlock::addFunctionExpr): (JSC::GlobalCodeBlock::GlobalCodeBlock): (JSC::ExecState::r):
  • bytecode/EvalCodeCache.h: (JSC::EvalCodeCache::get):
  • bytecode/SamplingTool.h: (JSC::ScriptSampleRecord::ScriptSampleRecord):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::addConstantValue): (JSC::BytecodeGenerator::emitEqualityOp):
  • bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::makeFunction):
  • debugger/Debugger.cpp: (JSC::evaluateInGlobalCallFrame):
  • debugger/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::evaluate):
  • interpreter/Interpreter.cpp: (JSC::Interpreter::callEval):
  • jit/JITInlineMethods.h: (JSC::JIT::emitLoadDouble): (JSC::JIT::emitLoadInt32ToDouble):
  • jit/JITStubs.cpp: (JSC::JITThunks::JITThunks): (JSC::JITThunks::hostFunctionStub): (JSC::JITThunks::clearHostFunctionStubs):
  • jit/JITStubs.h:
  • runtime/Completion.cpp: (JSC::checkSyntax): (JSC::evaluate):
  • runtime/Executable.cpp: (JSC::EvalExecutable::EvalExecutable): (JSC::ProgramExecutable::ProgramExecutable): (JSC::FunctionExecutable::FunctionExecutable): (JSC::FunctionExecutable::~FunctionExecutable): (JSC::EvalExecutable::markChildren): (JSC::ProgramExecutable::markChildren): (JSC::FunctionExecutable::markChildren): (JSC::FunctionExecutable::fromGlobalCode):
  • runtime/Executable.h: (JSC::ExecutableBase::ExecutableBase): (JSC::ExecutableBase::createStructure): (JSC::NativeExecutable::create): (JSC::NativeExecutable::NativeExecutable): (JSC::VPtrHackExecutable::VPtrHackExecutable): (JSC::ScriptExecutable::ScriptExecutable): (JSC::EvalExecutable::create): (JSC::EvalExecutable::createStructure): (JSC::ProgramExecutable::create): (JSC::ProgramExecutable::createStructure): (JSC::FunctionExecutable::create): (JSC::FunctionExecutable::createStructure):
  • runtime/FunctionConstructor.cpp: (JSC::constructFunction):
  • runtime/Heap.cpp: (JSC::Heap::destroy): (JSC::Heap::markRoots):
  • runtime/Heap.h:
  • runtime/JSActivation.cpp: (JSC::JSActivation::JSActivation): (JSC::JSActivation::markChildren):
  • runtime/JSActivation.h: (JSC::JSActivation::JSActivationData::JSActivationData):
  • runtime/JSCell.h:
  • runtime/JSFunction.cpp: (JSC::JSFunction::JSFunction): (JSC::JSFunction::~JSFunction): (JSC::JSFunction::markChildren):
  • runtime/JSFunction.h:
  • runtime/JSGlobalData.cpp: (JSC::JSGlobalData::storeVPtrs): (JSC::JSGlobalData::JSGlobalData): (JSC::JSGlobalData::getHostFunction):
  • runtime/JSGlobalData.h:
  • runtime/JSGlobalObjectFunctions.cpp: (JSC::globalFuncEval):
  • runtime/JSObject.cpp:
  • runtime/JSStaticScopeObject.cpp: (JSC::JSStaticScopeObject::markChildren):
  • runtime/JSStaticScopeObject.h: (JSC::JSStaticScopeObject::JSStaticScopeObjectData::JSStaticScopeObjectData): (JSC::JSStaticScopeObject::JSStaticScopeObject):
  • runtime/JSZombie.cpp: (JSC::JSZombie::leakedZombieStructure):
  • runtime/JSZombie.h: (JSC::JSZombie::createStructure):
  • runtime/MarkedSpace.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r79211 r80598  
    249249        CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable* symbolTable, bool isConstructor);
    250250
    251         DeprecatedPtr<JSGlobalObject> m_globalObject;
     251        WriteBarrier<JSGlobalObject> m_globalObject;
    252252        Heap* m_heap;
    253253
     
    360360#endif
    361361
    362         ScriptExecutable* ownerExecutable() const { return m_ownerExecutable; }
     362        ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); }
    363363
    364364        void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
     
    473473
    474474        size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
    475         void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
    476         Register& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
     475        void addConstant(JSValue v)
     476        {
     477            m_constantRegisters.append(WriteBarrier<Unknown>());
     478            m_constantRegisters.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), v);
     479        }
     480        WriteBarrier<Unknown>& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
    477481        ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
    478         ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); }
    479 
    480         unsigned addFunctionDecl(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; }
     482        ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
     483
     484        unsigned addFunctionDecl(FunctionExecutable* n)
     485        {
     486            unsigned size = m_functionDecls.size();
     487            m_functionDecls.append(WriteBarrier<FunctionExecutable>());
     488            m_functionDecls.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), n);
     489            return size;
     490        }
    481491        FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
    482492        int numberOfFunctionDecls() { return m_functionDecls.size(); }
    483         unsigned addFunctionExpr(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; }
     493        unsigned addFunctionExpr(FunctionExecutable* n)
     494        {
     495            unsigned size = m_functionExprs.size();
     496            m_functionExprs.append(WriteBarrier<FunctionExecutable>());
     497            m_functionExprs.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), n);
     498            return size;
     499        }
    484500        FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
    485501
     
    537553        }
    538554
    539         ScriptExecutable* m_ownerExecutable;
     555        WriteBarrier<ScriptExecutable> m_ownerExecutable;
    540556        JSGlobalData* m_globalData;
    541557
     
    575591        // Constant Pool
    576592        Vector<Identifier> m_identifiers;
    577         Vector<Register> m_constantRegisters;
    578         Vector<RefPtr<FunctionExecutable> > m_functionDecls;
    579         Vector<RefPtr<FunctionExecutable> > m_functionExprs;
     593        COMPILE_ASSERT(sizeof(Register) == sizeof(WriteBarrier<Unknown>), Register_must_be_same_size_as_WriteBarrier_Unknown);
     594        Vector<WriteBarrier<Unknown> > m_constantRegisters;
     595        Vector<WriteBarrier<FunctionExecutable> > m_functionDecls;
     596        Vector<WriteBarrier<FunctionExecutable> > m_functionExprs;
    580597
    581598        SymbolTable* m_symbolTable;
     
    618635            : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false)
    619636        {
    620             m_heap->codeBlocks().add(this);
    621         }
    622 
    623         ~GlobalCodeBlock()
    624         {
    625             m_heap->codeBlocks().remove(this);
    626637        }
    627638
     
    681692        CodeBlock* codeBlock = this->codeBlock();
    682693        if (codeBlock->isConstantRegisterIndex(index))
    683             return codeBlock->constantRegister(index);
     694            return *reinterpret_cast<Register*>(&codeBlock->constantRegister(index));
    684695        return this[index];
    685696    }
Note: See TracChangeset for help on using the changeset viewer.