Changeset 99898 in webkit


Ignore:
Timestamp:
Nov 10, 2011 1:59:39 PM (12 years ago)
Author:
fpizlo@apple.com
Message:

DFG should not reparse code that was just parsed
https://bugs.webkit.org/show_bug.cgi?id=71977

Reviewed by Geoff Garen.

The instruction stream of a code block is now kept around until
the next GC. When doing either an optimizing compilation of an
executable, or inlining of an executable, we now try to find the
already preexisting bytecode. If we find it, we don't have to parse.
If we don't find it, we parse as before. Inlining takes the extra
step of caching code blocks, so if the same executable gets inlined
multiple times into the same caller, then we parse it at most once
even if prior to inlining that executable did not have any code
blocks with an instruction stream.

Also fixed a silly bug where the strict mode for various operations
was being determined by looking at the machine code block rather
than the inlinee.

To enable the delete-on-next-GC policy, I introduced the notion
of an ultra weak finalizer, which anyone can register during
tracing. This is thread-safe (for parallel GC) and
stop-the-world-safe (so calls to free() are postponed until the
world is resumed). This required reusing some facilities previously
created for WeakReferenceHarvester, so I created a common utility
class. I also retweaked the handling of WeakReferenceHarvesters,
since they should be executed during stop-the-world since in the
future we may want to allow them to call drain().

2% win on SunSpider. 2% win on V8, when run in my harness. Neutral
elsewhere.

(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::visitAggregate):
(JSC::CodeBlock::copyPostParseDataFrom):
(JSC::CodeBlock::copyPostParseDataFromAlternative):
(JSC::CodeBlock::finalizeUnconditionally):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::canProduceCopyWithBytecode):
(JSC::CodeBlock::discardBytecodeLater):
(JSC::CodeBlock::handleBytecodeDiscardingOpportunity):
(JSC::GlobalCodeBlock::GlobalCodeBlock):
(JSC::ProgramCodeBlock::ProgramCodeBlock):
(JSC::EvalCodeBlock::EvalCodeBlock):
(JSC::FunctionCodeBlock::FunctionCodeBlock):
(JSC::BytecodeDestructionBlocker::BytecodeDestructionBlocker):
(JSC::BytecodeDestructionBlocker::~BytecodeDestructionBlocker):

  • dfg/DFGAssemblyHelpers.h:

(JSC::DFG::AssemblyHelpers::strictModeFor):

  • dfg/DFGByteCodeCache.h: Added.

(JSC::DFG::CodeBlockKey::CodeBlockKey):
(JSC::DFG::CodeBlockKey::operator==):
(JSC::DFG::CodeBlockKey::hash):
(JSC::DFG::CodeBlockKey::executable):
(JSC::DFG::CodeBlockKey::kind):
(JSC::DFG::CodeBlockKey::isHashTableDeletedValue):
(JSC::DFG::CodeBlockKeyHash::hash):
(JSC::DFG::CodeBlockKeyHash::equal):
(JSC::DFG::ByteCodeCache::ByteCodeCache):
(JSC::DFG::ByteCodeCache::~ByteCodeCache):
(JSC::DFG::ByteCodeCache::get):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleInlining):

  • dfg/DFGJITCodeGenerator32_64.cpp:

(JSC::DFG::JITCodeGenerator::cachedPutById):

  • dfg/DFGJITCodeGenerator64.cpp:

(JSC::DFG::JITCodeGenerator::cachedPutById):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • heap/Heap.cpp:

(JSC::Heap::finalizeUnconditionally):
(JSC::Heap::markRoots):
(JSC::Heap::collect):

  • heap/Heap.h:
  • heap/ListableHandler.h: Added.

(JSC::ListableHandler::ListableHandler):
(JSC::ListableHandler::~ListableHandler):
(JSC::ListableHandler::List::List):
(JSC::ListableHandler::List::addNotThreadSafe):
(JSC::ListableHandler::List::addThreadSafe):
(JSC::ListableHandler::List::hasNext):
(JSC::ListableHandler::List::removeNext):

  • heap/MarkStack.cpp:

(JSC::MarkStackThreadSharedData::MarkStackThreadSharedData):
(JSC::SlotVisitor::harvestWeakReferences):
(JSC::SlotVisitor::finalizeUnconditionally):

  • heap/MarkStack.h:

(JSC::MarkStack::addWeakReferenceHarvester):
(JSC::MarkStack::addUnconditionalFinalizer):

  • heap/SlotVisitor.h:
  • heap/UnconditionalFinalizer.h: Added.

(JSC::UnconditionalFinalizer::~UnconditionalFinalizer):

  • heap/WeakReferenceHarvester.h:

(JSC::WeakReferenceHarvester::WeakReferenceHarvester):
(JSC::WeakReferenceHarvester::~WeakReferenceHarvester):

  • runtime/Executable.cpp:

(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::baselineCodeBlockFor):
(JSC::FunctionExecutable::codeBlockWithBytecodeFor):
(JSC::FunctionExecutable::produceCodeBlockFor):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):

  • runtime/Executable.h:

(JSC::FunctionExecutable::profiledCodeBlockFor):

Location:
trunk/Source/JavaScriptCore
Files:
3 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r99895 r99898  
     12011-11-10  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should not reparse code that was just parsed
     4        https://bugs.webkit.org/show_bug.cgi?id=71977
     5
     6        Reviewed by Geoff Garen.
     7       
     8        The instruction stream of a code block is now kept around until
     9        the next GC. When doing either an optimizing compilation of an
     10        executable, or inlining of an executable, we now try to find the
     11        already preexisting bytecode. If we find it, we don't have to parse.
     12        If we don't find it, we parse as before. Inlining takes the extra
     13        step of caching code blocks, so if the same executable gets inlined
     14        multiple times into the same caller, then we parse it at most once
     15        even if prior to inlining that executable did not have any code
     16        blocks with an instruction stream.
     17       
     18        Also fixed a silly bug where the strict mode for various operations
     19        was being determined by looking at the machine code block rather
     20        than the inlinee.
     21
     22        To enable the delete-on-next-GC policy, I introduced the notion
     23        of an ultra weak finalizer, which anyone can register during
     24        tracing. This is thread-safe (for parallel GC) and
     25        stop-the-world-safe (so calls to free() are postponed until the
     26        world is resumed). This required reusing some facilities previously
     27        created for WeakReferenceHarvester, so I created a common utility
     28        class. I also retweaked the handling of WeakReferenceHarvesters,
     29        since they should be executed during stop-the-world since in the
     30        future we may want to allow them to call drain().
     31       
     32        2% win on SunSpider. 2% win on V8, when run in my harness. Neutral
     33        elsewhere.
     34
     35        * JavaScriptCore.xcodeproj/project.pbxproj:
     36        * bytecode/CodeBlock.cpp:
     37        (JSC::CodeBlock::CodeBlock):
     38        (JSC::CodeBlock::visitAggregate):
     39        (JSC::CodeBlock::copyPostParseDataFrom):
     40        (JSC::CodeBlock::copyPostParseDataFromAlternative):
     41        (JSC::CodeBlock::finalizeUnconditionally):
     42        * bytecode/CodeBlock.h:
     43        (JSC::CodeBlock::canProduceCopyWithBytecode):
     44        (JSC::CodeBlock::discardBytecodeLater):
     45        (JSC::CodeBlock::handleBytecodeDiscardingOpportunity):
     46        (JSC::GlobalCodeBlock::GlobalCodeBlock):
     47        (JSC::ProgramCodeBlock::ProgramCodeBlock):
     48        (JSC::EvalCodeBlock::EvalCodeBlock):
     49        (JSC::FunctionCodeBlock::FunctionCodeBlock):
     50        (JSC::BytecodeDestructionBlocker::BytecodeDestructionBlocker):
     51        (JSC::BytecodeDestructionBlocker::~BytecodeDestructionBlocker):
     52        * dfg/DFGAssemblyHelpers.h:
     53        (JSC::DFG::AssemblyHelpers::strictModeFor):
     54        * dfg/DFGByteCodeCache.h: Added.
     55        (JSC::DFG::CodeBlockKey::CodeBlockKey):
     56        (JSC::DFG::CodeBlockKey::operator==):
     57        (JSC::DFG::CodeBlockKey::hash):
     58        (JSC::DFG::CodeBlockKey::executable):
     59        (JSC::DFG::CodeBlockKey::kind):
     60        (JSC::DFG::CodeBlockKey::isHashTableDeletedValue):
     61        (JSC::DFG::CodeBlockKeyHash::hash):
     62        (JSC::DFG::CodeBlockKeyHash::equal):
     63        (JSC::DFG::ByteCodeCache::ByteCodeCache):
     64        (JSC::DFG::ByteCodeCache::~ByteCodeCache):
     65        (JSC::DFG::ByteCodeCache::get):
     66        * dfg/DFGByteCodeParser.cpp:
     67        (JSC::DFG::ByteCodeParser::handleInlining):
     68        * dfg/DFGJITCodeGenerator32_64.cpp:
     69        (JSC::DFG::JITCodeGenerator::cachedPutById):
     70        * dfg/DFGJITCodeGenerator64.cpp:
     71        (JSC::DFG::JITCodeGenerator::cachedPutById):
     72        * dfg/DFGSpeculativeJIT64.cpp:
     73        (JSC::DFG::SpeculativeJIT::compile):
     74        * heap/Heap.cpp:
     75        (JSC::Heap::finalizeUnconditionally):
     76        (JSC::Heap::markRoots):
     77        (JSC::Heap::collect):
     78        * heap/Heap.h:
     79        * heap/ListableHandler.h: Added.
     80        (JSC::ListableHandler::ListableHandler):
     81        (JSC::ListableHandler::~ListableHandler):
     82        (JSC::ListableHandler::List::List):
     83        (JSC::ListableHandler::List::addNotThreadSafe):
     84        (JSC::ListableHandler::List::addThreadSafe):
     85        (JSC::ListableHandler::List::hasNext):
     86        (JSC::ListableHandler::List::removeNext):
     87        * heap/MarkStack.cpp:
     88        (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData):
     89        (JSC::SlotVisitor::harvestWeakReferences):
     90        (JSC::SlotVisitor::finalizeUnconditionally):
     91        * heap/MarkStack.h:
     92        (JSC::MarkStack::addWeakReferenceHarvester):
     93        (JSC::MarkStack::addUnconditionalFinalizer):
     94        * heap/SlotVisitor.h:
     95        * heap/UnconditionalFinalizer.h: Added.
     96        (JSC::UnconditionalFinalizer::~UnconditionalFinalizer):
     97        * heap/WeakReferenceHarvester.h:
     98        (JSC::WeakReferenceHarvester::WeakReferenceHarvester):
     99        (JSC::WeakReferenceHarvester::~WeakReferenceHarvester):
     100        * runtime/Executable.cpp:
     101        (JSC::EvalExecutable::compileInternal):
     102        (JSC::ProgramExecutable::compileInternal):
     103        (JSC::FunctionExecutable::baselineCodeBlockFor):
     104        (JSC::FunctionExecutable::codeBlockWithBytecodeFor):
     105        (JSC::FunctionExecutable::produceCodeBlockFor):
     106        (JSC::FunctionExecutable::compileForCallInternal):
     107        (JSC::FunctionExecutable::compileForConstructInternal):
     108        * runtime/Executable.h:
     109        (JSC::FunctionExecutable::profiledCodeBlockFor):
     110
    11112011-11-10  Gavin Barraclough  <barraclough@apple.com>
    2112
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r99787 r99898  
    5555                0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; };
    5656                0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
     57                0F431738146BAC69007E3890 /* ListableHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F431736146BAC65007E3890 /* ListableHandler.h */; settings = {ATTRIBUTES = (Private, ); }; };
     58                0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
    5759                0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; settings = {ATTRIBUTES = (Private, ); }; };
    5860                0F620175143FCD370068B77C /* DFGOperands.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620171143FCD2F0068B77C /* DFGOperands.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    830832                0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; };
    831833                0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; };
     834                0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; };
     835                0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; };
     836                0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; };
    832837                0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractState.cpp; path = dfg/DFGAbstractState.cpp; sourceTree = "<group>"; };
    833838                0F62016E143FCD2F0068B77C /* DFGAbstractState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractState.h; path = dfg/DFGAbstractState.h; sourceTree = "<group>"; };
     
    17021707                        isa = PBXGroup;
    17031708                        children = (
     1709                                0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */,
     1710                                0F431736146BAC65007E3890 /* ListableHandler.h */,
    17041711                                0FD82F281426CA5A00179C94 /* JettisonedCodeBlocks.cpp */,
    17051712                                0FD82F291426CA5A00179C94 /* JettisonedCodeBlocks.h */,
     
    23182325                        isa = PBXGroup;
    23192326                        children = (
     2327                                0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */,
    23202328                                0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
    23212329                                0FC097A0146B28C700CF2442 /* DFGThunks.h */,
     
    29442952                                0FC0979C146A772500CF2442 /* DFGCorrectableJumpPoint.h in Headers */,
    29452953                                0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */,
     2954                                0F431738146BAC69007E3890 /* ListableHandler.h in Headers */,
     2955                                0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */,
    29462956                        );
    29472957                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r99810 r99898  
    14081408}
    14091409
     1410CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
     1411    : m_globalObject(other.m_globalObject)
     1412    , m_heap(other.m_heap)
     1413    , m_numCalleeRegisters(other.m_numCalleeRegisters)
     1414    , m_numVars(other.m_numVars)
     1415    , m_numCapturedVars(other.m_numCapturedVars)
     1416    , m_numParameters(other.m_numParameters)
     1417    , m_isConstructor(other.m_isConstructor)
     1418    , m_shouldDiscardBytecode(false)
     1419    , m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
     1420    , m_globalData(other.m_globalData)
     1421    , m_instructions(other.m_instructions)
     1422    , m_instructionCount(other.m_instructionCount)
     1423    , m_thisRegister(other.m_thisRegister)
     1424    , m_argumentsRegister(other.m_argumentsRegister)
     1425    , m_activationRegister(other.m_activationRegister)
     1426    , m_needsFullScopeChain(other.m_needsFullScopeChain)
     1427    , m_usesEval(other.m_usesEval)
     1428    , m_isNumericCompareFunction(other.m_isNumericCompareFunction)
     1429    , m_isStrictMode(other.m_isStrictMode)
     1430    , m_codeType(other.m_codeType)
     1431    , m_source(other.m_source)
     1432    , m_sourceOffset(other.m_sourceOffset)
     1433    , m_globalResolveInfos(other.m_globalResolveInfos)
     1434    , m_jumpTargets(other.m_jumpTargets)
     1435    , m_loopTargets(other.m_loopTargets)
     1436    , m_identifiers(other.m_identifiers)
     1437    , m_constantRegisters(other.m_constantRegisters)
     1438    , m_functionDecls(other.m_functionDecls)
     1439    , m_functionExprs(other.m_functionExprs)
     1440    , m_symbolTable(symTab)
     1441    , m_speculativeSuccessCounter(0)
     1442    , m_speculativeFailCounter(0)
     1443    , m_optimizationDelayCounter(0)
     1444    , m_reoptimizationRetryCounter(0)
     1445{
     1446    optimizeAfterWarmUp();
     1447   
     1448    if (other.m_rareData) {
     1449        createRareDataIfNecessary();
     1450       
     1451        m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers;
     1452        m_rareData->m_regexps = other.m_rareData->m_regexps;
     1453        m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers;
     1454        m_rareData->m_immediateSwitchJumpTables = other.m_rareData->m_immediateSwitchJumpTables;
     1455        m_rareData->m_characterSwitchJumpTables = other.m_rareData->m_characterSwitchJumpTables;
     1456        m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
     1457        m_rareData->m_expressionInfo = other.m_rareData->m_expressionInfo;
     1458        m_rareData->m_lineInfo = other.m_rareData->m_lineInfo;
     1459    }
     1460}
     1461
    14101462CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor, PassOwnPtr<CodeBlock> alternative)
    14111463    : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject)
     
    14151467    , m_numParameters(0)
    14161468    , m_isConstructor(isConstructor)
     1469    , m_shouldDiscardBytecode(false)
    14171470    , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
    14181471    , m_globalData(0)
     
    15961649        valueProfile(profileIndex)->computeUpdatedPrediction();
    15971650#endif
     1651   
     1652#if ENABLE(JIT) && !ENABLE(OPCODE_SAMPLING)
     1653    // Kill off some bytecode. We can't do it here because we don't want to accidentally
     1654    // call into malloc while in stop-the-world GC mode.
     1655    if (hasInstructions() && m_shouldDiscardBytecode)
     1656        visitor.addUnconditionalFinalizer(this);
     1657#endif
    15981658}
    15991659
     
    18221882}
    18231883
    1824 void CodeBlock::copyDataFrom(CodeBlock* alternative)
     1884void CodeBlock::copyPostParseDataFrom(CodeBlock* alternative)
    18251885{
    18261886    if (!alternative)
     
    18341894}
    18351895
    1836 void CodeBlock::copyDataFromAlternative()
    1837 {
    1838     copyDataFrom(m_alternative.get());
     1896void CodeBlock::copyPostParseDataFromAlternative()
     1897{
     1898    copyPostParseDataFrom(m_alternative.get());
    18391899}
    18401900
     
    19171977}
    19181978#endif
     1979
     1980void CodeBlock::finalizeUnconditionally()
     1981{
     1982#if ENABLE(OPCODE_SAMPLING) || !ENABLE(JIT)
     1983    ASSERT_NOT_REACHED();
     1984#endif
     1985    ASSERT(m_shouldDiscardBytecode);
     1986    discardBytecode();
     1987}
    19191988
    19201989#if ENABLE(VALUE_PROFILER)
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r99810 r99898  
    4646#include "RegExpObject.h"
    4747#include "UString.h"
     48#include "UnconditionalFinalizer.h"
    4849#include "ValueProfile.h"
    4950#include <wtf/FastAllocBase.h>
     
    237238#endif
    238239
    239     class CodeBlock {
     240    class CodeBlock : public UnconditionalFinalizer {
    240241        WTF_MAKE_FAST_ALLOCATED;
    241242        friend class JIT;
     243    public:
     244        enum CopyParsedBlockTag { CopyParsedBlock };
    242245    protected:
     246        CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable*);
     247       
    243248        CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable*, bool isConstructor, PassOwnPtr<CodeBlock> alternative);
    244249
     
    266271        }
    267272#endif
     273       
     274        bool canProduceCopyWithBytecode() { return hasInstructions(); }
    268275
    269276        void visitAggregate(SlotVisitor&);
     
    444451        const Vector<Instruction>& instructions() const { return m_instructions->m_instructions; }
    445452        void discardBytecode() { m_instructions.clear(); }
    446 
     453        void discardBytecodeLater()
     454        {
     455            m_shouldDiscardBytecode = true;
     456        }
     457        void handleBytecodeDiscardingOpportunity()
     458        {
     459            if (!!alternative())
     460                discardBytecode();
     461            else
     462                discardBytecodeLater();
     463        }
     464       
    447465#ifndef NDEBUG
    448466        bool usesOpcode(OpcodeID);
     
    809827        void shrinkToFit();
    810828       
    811         void copyDataFrom(CodeBlock* alternative);
    812         void copyDataFromAlternative();
     829        void copyPostParseDataFrom(CodeBlock* alternative);
     830        void copyPostParseDataFromAlternative();
    813831       
    814832        // Functions for controlling when tiered compilation kicks in. This
     
    9971015        bool m_isConstructor;
    9981016
     1017        // This is public because otherwise we would have many friends.
     1018        bool m_shouldDiscardBytecode;
     1019
     1020    protected:
     1021        virtual void finalizeUnconditionally();
     1022       
    9991023    private:
    10001024#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
     
    10151039                m_rareData = adoptPtr(new RareData);
    10161040        }
    1017 
     1041       
    10181042        WriteBarrier<ScriptExecutable> m_ownerExecutable;
    10191043        JSGlobalData* m_globalData;
     
    11301154    class GlobalCodeBlock : public CodeBlock {
    11311155    protected:
     1156        GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
     1157            : CodeBlock(CopyParsedBlock, other, &m_unsharedSymbolTable)
     1158            , m_unsharedSymbolTable(other.m_unsharedSymbolTable)
     1159        {
     1160        }
     1161       
    11321162        GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
    11331163            : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false, alternative)
     
    11411171    class ProgramCodeBlock : public GlobalCodeBlock {
    11421172    public:
     1173        ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other)
     1174            : GlobalCodeBlock(CopyParsedBlock, other)
     1175        {
     1176        }
     1177
    11431178        ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, PassOwnPtr<CodeBlock> alternative)
    11441179            : GlobalCodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, 0, alternative)
     
    11571192    class EvalCodeBlock : public GlobalCodeBlock {
    11581193    public:
     1194        EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
     1195            : GlobalCodeBlock(CopyParsedBlock, other)
     1196            , m_baseScopeDepth(other.m_baseScopeDepth)
     1197            , m_variables(other.m_variables)
     1198        {
     1199        }
     1200       
    11591201        EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth, PassOwnPtr<CodeBlock> alternative)
    11601202            : GlobalCodeBlock(ownerExecutable, EvalCode, globalObject, sourceProvider, 0, alternative)
     
    11881230    class FunctionCodeBlock : public CodeBlock {
    11891231    public:
     1232        FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
     1233            : CodeBlock(CopyParsedBlock, other, other.sharedSymbolTable())
     1234        {
     1235            // The fact that we have to do this is yucky, but is necessary because of the
     1236            // class hierarchy issues described in the comment block for the main
     1237            // constructor, below.
     1238            sharedSymbolTable()->ref();
     1239        }
     1240
    11901241        // Rather than using the usual RefCounted::create idiom for SharedSymbolTable we just use new
    11911242        // as we need to initialise the CodeBlock before we could initialise any RefPtr to hold the shared
     
    12081259        virtual bool canCompileWithDFG();
    12091260#endif
     1261    };
     1262
     1263    // Use this if you want to copy a code block and you're paranoid about a GC
     1264    // happening.
     1265    class BytecodeDestructionBlocker {
     1266    public:
     1267        BytecodeDestructionBlocker(CodeBlock* codeBlock)
     1268            : m_codeBlock(codeBlock)
     1269            , m_oldValueOfShouldDiscardBytecode(codeBlock->m_shouldDiscardBytecode)
     1270        {
     1271            codeBlock->m_shouldDiscardBytecode = false;
     1272        }
     1273       
     1274        ~BytecodeDestructionBlocker()
     1275        {
     1276            m_codeBlock->m_shouldDiscardBytecode = m_oldValueOfShouldDiscardBytecode;
     1277        }
     1278       
     1279    private:
     1280        CodeBlock* m_codeBlock;
     1281        bool m_oldValueOfShouldDiscardBytecode;
    12101282    };
    12111283
  • trunk/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h

    r99888 r99898  
    238238    }
    239239   
     240    bool strictModeFor(CodeOrigin codeOrigin)
     241    {
     242        if (!codeOrigin.inlineCallFrame)
     243            return codeBlock()->isStrictMode();
     244        return codeOrigin.inlineCallFrame->callee->jsExecutable()->isStrictMode();
     245    }
     246   
    240247    CodeBlock* baselineCodeBlockFor(const CodeOrigin& codeOrigin)
    241248    {
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r99788 r99898  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include "DFGByteCodeCache.h"
    3132#include "DFGCapabilities.h"
    3233#include "CodeBlock.h"
     
    842843    // Mapping between values and constant numbers.
    843844    JSValueMap m_jsValueMap;
     845   
     846    // Cache of code blocks that we've generated bytecode for.
     847    ByteCodeCache<canInlineFunctionFor> m_codeBlockCache;
    844848};
    845849
     
    957961    // If we get here then it looks like we should definitely inline this code. Proceed
    958962    // with parsing the code to get bytecode, so that we can then parse the bytecode.
    959     // Note that the code block we get here is intended to die after handleInlining()
    960     // returns.
    961     JSObject* exception;
    962     OwnPtr<CodeBlock> codeBlock = executable->produceCodeBlockFor(expectedFunction->scope(), OptimizingCompilation, kind, exception);
     963    CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope());
    963964    if (!codeBlock)
    964965        return false;
    965     ASSERT(!exception);
    966    
    967     // Now that we have the bytecode, check if we really can inline it. This may fail
    968     // if the code block contains some nasty opcodes.
    969     if (!canInlineFunctionFor(codeBlock.get(), kind))
    970         return false;
     966   
     967    ASSERT(canInlineFunctionFor(codeBlock, kind));
    971968
    972969#if DFG_ENABLE(DEBUG_VERBOSE)
     
    999996    }
    1000997
    1001     InlineStackEntry inlineStackEntry(this, codeBlock.get(), profiledBlock, m_graph.m_blocks.size() - 1, (VirtualRegister)m_inlineStackTop->remapOperand(callTarget), expectedFunction, (VirtualRegister)m_inlineStackTop->remapOperand(usesResult ? resultOperand : InvalidVirtualRegister), (VirtualRegister)inlineCallFrameStart, kind);
     998    InlineStackEntry inlineStackEntry(this, codeBlock, profiledBlock, m_graph.m_blocks.size() - 1, (VirtualRegister)m_inlineStackTop->remapOperand(callTarget), expectedFunction, (VirtualRegister)m_inlineStackTop->remapOperand(usesResult ? resultOperand : InvalidVirtualRegister), (VirtualRegister)inlineCallFrameStart, kind);
    1002999   
    10031000    // This is where the actual inlining really happens.
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp

    r99622 r99898  
    909909    silentSpillAllRegisters(InvalidGPRReg);
    910910    V_DFGOperation_EJCI optimizedCall;
    911     if (m_jit.codeBlock()->isStrictMode()) {
     911    if (m_jit.strictModeFor(at(m_compileIndex).codeOrigin)) {
    912912        if (putKind == Direct)
    913913            optimizedCall = operationPutByIdDirectStrictOptimize;
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp

    r99622 r99898  
    838838    silentSpillAllRegisters(InvalidGPRReg);
    839839    V_DFGOperation_EJCI optimizedCall;
    840     if (m_jit.codeBlock()->isStrictMode()) {
     840    if (m_jit.strictModeFor(at(m_compileIndex).codeOrigin)) {
    841841        if (putKind == Direct)
    842842            optimizedCall = operationPutByIdDirectStrictOptimize;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r99765 r99898  
    15071507            flushRegisters();
    15081508           
    1509             callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
     1509            callOperation(m_jit.strictModeFor(node.codeOrigin) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
    15101510           
    15111511            noResult(m_compileIndex);
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r99477 r99898  
    531531}
    532532
     533void Heap::finalizeUnconditionalFinalizers()
     534{
     535    m_slotVisitor.finalizeUnconditionalFinalizers();
     536}
     537
    533538inline RegisterFile& Heap::registerFile()
    534539{
     
    695700    }
    696701    GCCOUNTER(VisitedValueCount, visitor.visitCount());
     702
     703    {
     704        GCPHASE(HarvestWeakReferences);
     705        harvestWeakReferences();
     706    }
     707
    697708    visitor.reset();
    698709    m_sharedData.reset();
     
    782793
    783794    markRoots(fullGC);
    784 
    785     {
    786         GCPHASE(HarvestWeakReferences);
    787         harvestWeakReferences();
     795   
     796    {
     797        GCPHASE(FinalizeUnconditionalFinalizers);
     798        finalizeUnconditionalFinalizers();
     799    }
     800       
     801    {
     802        GCPHASE(FinalizeWeakHandles);
    788803        m_handleHeap.finalizeWeakHandles();
    789804        m_globalData->smallStrings.finalizeSmallStrings();
    790805    }
    791 
     806   
    792807    JAVASCRIPTCORE_GC_MARKED();
    793808
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r98937 r99898  
    156156        void markTempSortVectors(HeapRootVisitor&);
    157157        void harvestWeakReferences();
     158        void finalizeUnconditionalFinalizers();
    158159       
    159160        enum SweepToggle { DoNotSweep, DoSweep };
  • trunk/Source/JavaScriptCore/heap/MarkStack.cpp

    r98937 r99898  
    237237    , m_numberOfActiveParallelMarkers(0)
    238238    , m_parallelMarkersShouldExit(false)
    239     , m_firstWeakReferenceHarvester(0)
    240239{
    241240#if ENABLE(PARALLEL_GC)
     
    451450void SlotVisitor::harvestWeakReferences()
    452451{
    453     while (m_shared.m_firstWeakReferenceHarvester) {
    454         WeakReferenceHarvester* current = m_shared.m_firstWeakReferenceHarvester;
    455         WeakReferenceHarvester* next = reinterpret_cast<WeakReferenceHarvester*>(current->m_nextAndFlag & ~1);
    456         current->m_nextAndFlag = 0;
    457         m_shared.m_firstWeakReferenceHarvester = next;
    458         current->visitWeakReferences(*this);
    459     }
     452    while (m_shared.m_weakReferenceHarvesters.hasNext())
     453        m_shared.m_weakReferenceHarvesters.removeNext()->visitWeakReferences(*this);
     454}
     455
     456void SlotVisitor::finalizeUnconditionalFinalizers()
     457{
     458    while (m_shared.m_unconditionalFinalizers.hasNext())
     459        m_shared.m_unconditionalFinalizers.removeNext()->finalizeUnconditionally();
    460460}
    461461
  • trunk/Source/JavaScriptCore/heap/MarkStack.h

    r98937 r99898  
    3131#include "JSValue.h"
    3232#include "Register.h"
     33#include "UnconditionalFinalizer.h"
    3334#include "VTableSpectrum.h"
    3435#include "WeakReferenceHarvester.h"
     
    195196        HashSet<void*> m_opaqueRoots;
    196197
    197         Mutex m_weakReferenceHarvesterLock;
    198         WeakReferenceHarvester* m_firstWeakReferenceHarvester;
     198        ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters;
     199        ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers;
    199200    };
    200201
     
    230231        void addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester)
    231232        {
    232             MutexLocker locker(m_shared.m_weakReferenceHarvesterLock);
    233             if (weakReferenceHarvester->m_nextAndFlag & 1)
    234                 return;
    235             weakReferenceHarvester->m_nextAndFlag = reinterpret_cast<uintptr_t>(m_shared.m_firstWeakReferenceHarvester) | 1;
    236             m_shared.m_firstWeakReferenceHarvester = weakReferenceHarvester;
     233            m_shared.m_weakReferenceHarvesters.addThreadSafe(weakReferenceHarvester);
     234        }
     235       
     236        void addUnconditionalFinalizer(UnconditionalFinalizer* unconditionalFinalizer)
     237        {
     238            m_shared.m_unconditionalFinalizers.addThreadSafe(unconditionalFinalizer);
    237239        }
    238240
  • trunk/Source/JavaScriptCore/heap/SlotVisitor.h

    r98937 r99898  
    5959
    6060    void harvestWeakReferences();
     61    void finalizeUnconditionalFinalizers();
    6162       
    6263private:
  • trunk/Source/JavaScriptCore/heap/WeakReferenceHarvester.h

    r98937 r99898  
    2121#define WeakReferenceHarvester_h
    2222
    23 #include <stdint.h>
     23#include "ListableHandler.h"
    2424
    2525namespace JSC {
     
    2929class SlotVisitor;
    3030
    31 class WeakReferenceHarvester {
     31class WeakReferenceHarvester : public ListableHandler<WeakReferenceHarvester> {
    3232public:
    3333    virtual void visitWeakReferences(SlotVisitor&) = 0;
     
    3535protected:
    3636    WeakReferenceHarvester()
    37         : m_nextAndFlag(0)
    3837    {
    3938    }
    4039   
    4140    virtual ~WeakReferenceHarvester() { }
    42 
    43 private:
    44     friend class MarkStack;
    45     friend class MarkStackSharedData;
    46     friend class SlotVisitor;
    47    
    48     uintptr_t m_nextAndFlag;
    4941};
    5042
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r99374 r99898  
    157157    JSGlobalData* globalData = &exec->globalData();
    158158    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    159     if (!lexicalGlobalObject->evalEnabled())
    160         return throwError(exec, createEvalError(exec, "Eval is disabled"));
    161     RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
    162     if (!evalNode) {
    163         ASSERT(exception);
    164         return exception;
    165     }
    166     recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
    167 
    168     JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
    169 
    170     OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
    171     ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
    172     m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release()));
    173     OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
    174     if ((exception = generator->generate())) {
    175         m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
     159   
     160    if (!!m_evalCodeBlock && m_evalCodeBlock->canProduceCopyWithBytecode()) {
     161        BytecodeDestructionBlocker blocker(m_evalCodeBlock.get());
     162        OwnPtr<EvalCodeBlock> newCodeBlock = adoptPtr(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));
     163        newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock.release()));
     164        m_evalCodeBlock = newCodeBlock.release();
     165    } else {
     166        if (!lexicalGlobalObject->evalEnabled())
     167            return throwError(exec, createEvalError(exec, "Eval is disabled"));
     168        RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
     169        if (!evalNode) {
     170            ASSERT(exception);
     171            return exception;
     172        }
     173        recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
     174       
     175        JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
     176       
     177        OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
     178        ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
     179        m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release()));
     180        OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
     181        if ((exception = generator->generate())) {
     182            m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
     183            evalNode->destroyData();
     184            return exception;
     185        }
     186       
    176187        evalNode->destroyData();
    177         return exception;
    178     }
    179 
    180     evalNode->destroyData();
    181     m_evalCodeBlock->copyDataFromAlternative();
     188        m_evalCodeBlock->copyPostParseDataFromAlternative();
     189    }
    182190
    183191#if ENABLE(JIT)
     
    199207#if !ENABLE(OPCODE_SAMPLING)
    200208        if (!BytecodeGenerator::dumpsGeneratedCode())
    201             m_evalCodeBlock->discardBytecode();
     209            m_evalCodeBlock->handleBytecodeDiscardingOpportunity();
    202210#endif
    203211        m_evalCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr());
     
    291299    JSGlobalData* globalData = &exec->globalData();
    292300    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    293     RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
    294     if (!programNode) {
    295         ASSERT(exception);
    296         return exception;
    297     }
    298     recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());
    299 
    300     JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
    301    
    302     OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release();
    303     ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
    304     m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release()));
    305     OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
    306     if ((exception = generator->generate())) {
    307         m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative());
     301   
     302    if (!!m_programCodeBlock && m_programCodeBlock->canProduceCopyWithBytecode()) {
     303        BytecodeDestructionBlocker blocker(m_programCodeBlock.get());
     304        OwnPtr<ProgramCodeBlock> newCodeBlock = adoptPtr(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock));
     305        newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock.release()));
     306        m_programCodeBlock = newCodeBlock.release();
     307    } else {
     308        RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
     309        if (!programNode) {
     310            ASSERT(exception);
     311            return exception;
     312        }
     313        recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());
     314
     315        JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
     316   
     317        OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release();
     318        ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
     319        m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release()));
     320        OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
     321        if ((exception = generator->generate())) {
     322            m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative());
     323            programNode->destroyData();
     324            return exception;
     325        }
     326
    308327        programNode->destroyData();
    309         return exception;
    310     }
    311 
    312     programNode->destroyData();
    313     m_programCodeBlock->copyDataFromAlternative();
     328        m_programCodeBlock->copyPostParseDataFromAlternative();
     329    }
    314330
    315331#if ENABLE(JIT)
     
    330346#if !ENABLE(OPCODE_SAMPLING)
    331347        if (!BytecodeGenerator::dumpsGeneratedCode())
    332             m_programCodeBlock->discardBytecode();
     348            m_programCodeBlock->handleBytecodeDiscardingOpportunity();
    333349#endif
    334350        m_programCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr());
     
    389405}
    390406
    391 CodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKind kind)
    392 {
    393     CodeBlock* result;
     407FunctionCodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKind kind)
     408{
     409    FunctionCodeBlock* result;
    394410    if (kind == CodeForCall)
    395411        result = m_codeBlockForCall.get();
     
    401417        return 0;
    402418    while (result->alternative())
    403         result = result->alternative();
     419        result = static_cast<FunctionCodeBlock*>(result->alternative());
    404420    ASSERT(result);
    405421    ASSERT(result->getJITType() == JITCode::BaselineJIT);
     
    429445}
    430446
     447FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind)
     448{
     449    FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind);
     450    if (codeBlock->canProduceCopyWithBytecode())
     451        return codeBlock;
     452    return 0;
     453}
     454
    431455PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChainNode* scopeChainNode, CompilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception)
    432456{
     457    if (!!codeBlockFor(specializationKind) && codeBlockFor(specializationKind)->canProduceCopyWithBytecode()) {
     458        BytecodeDestructionBlocker blocker(codeBlockFor(specializationKind).get());
     459        return adoptPtr(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));
     460    }
     461   
    433462    exception = 0;
    434463    JSGlobalData* globalData = scopeChainNode->globalData;
     
    454483        return nullptr;
    455484
    456     result->copyDataFrom(codeBlockFor(specializationKind).get());
     485    result->copyPostParseDataFrom(codeBlockFor(specializationKind).get());
    457486    return result.release();
    458487}
     
    499528#if !ENABLE(OPCODE_SAMPLING)
    500529        if (!BytecodeGenerator::dumpsGeneratedCode())
    501             m_codeBlockForCall->discardBytecode();
     530            m_codeBlockForCall->handleBytecodeDiscardingOpportunity();
    502531#endif
    503532       
     
    562591#if !ENABLE(OPCODE_SAMPLING)
    563592        if (!BytecodeGenerator::dumpsGeneratedCode())
    564             m_codeBlockForConstruct->discardBytecode();
     593            m_codeBlockForConstruct->handleBytecodeDiscardingOpportunity();
    565594#endif
    566595       
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r98214 r99898  
    479479        }
    480480       
     481        FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind);
     482       
    481483        PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(ScopeChainNode*, CompilationKind, CodeSpecializationKind, JSObject*& exception);
    482484
     
    587589        }
    588590
    589         CodeBlock* baselineCodeBlockFor(CodeSpecializationKind);
    590        
    591         CodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)
     591        FunctionCodeBlock* baselineCodeBlockFor(CodeSpecializationKind);
     592       
     593        FunctionCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)
    592594        {
    593595            return baselineCodeBlockFor(kind);
Note: See TracChangeset for help on using the changeset viewer.