Changeset 159136 in webkit


Ignore:
Timestamp:
Nov 12, 2013 12:35:34 PM (10 years ago)
Author:
mhahnenberg@apple.com
Message:

CodeBlocks should be able to determine bytecode liveness
https://bugs.webkit.org/show_bug.cgi?id=118546

Reviewed by Filip Pizlo.

This will simplify some things in the DFG related to OSR exits and determining
which bytecode variables are live at which points during execution. It will
also be useful for making our conservative GC scan more precise. Currently it
doesn't properly account for liveness while the DFG is running, so it will be
off by default behing a runtime Options flag.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/BytecodeBasicBlock.cpp: Added.

(JSC::isBranch): Used to determine the end of basic blocks.
(JSC::isUnconditionalBranch): Used to determine when a branch at the end of a
basic block can't possibly fall through to the next basic block in program order.
(JSC::isTerminal): Also used to detect the end of a block.
(JSC::isThrow):
(JSC::isJumpTarget): Used to correctly separate basic blocks. Any jump destination
must be the head of its own basic block.
(JSC::linkBlocks): Links two blocks together in a bi-direcitonal fashion.
(JSC::computeBytecodeBasicBlocks): Creates a set of basic blocks given a particular
CodeBlock and links them together.

  • bytecode/BytecodeBasicBlock.h: Added.

(JSC::BytecodeBasicBlock::isEntryBlock): Entry blocks are a special basic blocks
that indicate the beginning of the function.
(JSC::BytecodeBasicBlock::isExitBlock): Exit blocks are a special basic block that
all blocks that exit the function have as a successor. Entry and exit blocks allows
the various code paths to be more regular.
(JSC::BytecodeBasicBlock::leaderBytecodeOffset): The leader bytecode offset is the
bytecode offset of the first instruction in the block.
(JSC::BytecodeBasicBlock::totalBytecodeLength): The total length of all the bytecodes
in this block.
(JSC::BytecodeBasicBlock::bytecodeOffsets): The bytecode offsets in this particular
basic block. This Vector allows us to iterate over the bytecodes in reverse order
which wouldn't be possible normally since they are of variable size.
(JSC::BytecodeBasicBlock::addPredecessor): Links a block to a specified predecessor.
Only creates one direction of the link.
(JSC::BytecodeBasicBlock::addSuccessor): Same as addPredecessor, but for successors.
(JSC::BytecodeBasicBlock::predecessors): Getter for predecessors.
(JSC::BytecodeBasicBlock::successors): Getter for successors.
(JSC::BytecodeBasicBlock::in): Getter for the liveness info at the head of the block.
(JSC::BytecodeBasicBlock::out): Getter for the liveness info at the tail of the block.
(JSC::BytecodeBasicBlock::BytecodeBasicBlock):
(JSC::BytecodeBasicBlock::addBytecodeLength): When creating basic blocks we call
this function when we want to add the next bytecode in program order to this block.

  • bytecode/BytecodeLivenessAnalysis.cpp: Added.

(JSC::BytecodeLivenessAnalysis::BytecodeLivenessAnalysis):
(JSC::numberOfCapturedVariables): Convenience wrapper. Returns the
number of captured variables for a particular CodeBlock, or 0 if
the CodeBlock has no SymbolTable.
(JSC::captureStart): Ditto, but for captureStart().
(JSC::captureEnd): Ditto, but for captureEnd().
(JSC::isValidRegisterForLiveness): Returns true if the liveness analysis should
track the liveness of a particular operand. We ignore constants, arguments, and
captured variables. We ignore arguments because they're live for the duration of
a function call. We ignore captured variables because we also treat them as live
for the duration of the function. This could probably be improved to be more precise,
but it didn't seem worth it for now.
(JSC::setForOperand): Convenience wrapper that sets the bit in the provided bit
vector for the provided operand. It handles skipping over captured variables.
(JSC::computeUsesForBytecodeOffset): Computes which operands are used by a particular bytecode.
(JSC::computeDefsForBytecodeOffset): Computes which operands are defined by a particular
bytecode. Typically this is just the left-most operand.
(JSC::findBasicBlockWithLeaderOffset):
(JSC::findBasicBlockForBytecodeOffset): Scans over basic blocks to find the block
which contains a particular bytecode offset.
(JSC::computeLocalLivenessForBytecodeOffset): Computes block-local liveness from the
bottom of the block until a specified bytecode offset is reached.
(JSC::computeLocalLivenessForBlock): Computes liveness for the entire block and
stores the resulting liveness at the head.
(JSC::BytecodeLivenessAnalysis::runLivenessFixpoint): Runs backward flow liveness
analysis to fixpoint.
(JSC::BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset):
Slow path to get liveness info for non-captured, non-argument variable.
(JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
(JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset): Returns the liveness
info for both captured and non-captured vars at a particular bytecode offset.
(JSC::BytecodeLivenessAnalysis::dumpResults): Dumps the output of the liveness analysis.
Controlled by new flag in Options.h/.cpp.
(JSC::BytecodeLivenessAnalysis::compute): Creates bytecode basic blocks and runs
full liveness analysis.

  • bytecode/BytecodeLivenessAnalysis.h: Added.

(JSC::BytecodeLivenessAnalysis::hasBeenComputed):
(JSC::BytecodeLivenessAnalysis::computeIfNecessary):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::livenessAnalysis):

  • bytecode/PreciseJumpTargets.cpp: Refactored to be able to get the jump targets for

a particular bytecode offset for use during bytecode basic block construction.
(JSC::getJumpTargetsForBytecodeOffset):
(JSC::computePreciseJumpTargets):
(JSC::findJumpTargetsForBytecodeOffset):

  • bytecode/PreciseJumpTargets.h:
  • runtime/Options.cpp:

(JSC::Options::initialize):

  • runtime/Options.h:
Location:
trunk/Source
Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r159031 r159136  
    4747    bytecode/ArrayAllocationProfile.cpp
    4848    bytecode/ArrayProfile.cpp
     49    bytecode/BytecodeBasicBlock.cpp
     50    bytecode/BytecodeLivenessAnalysis.cpp
    4951    bytecode/CallLinkInfo.cpp
    5052    bytecode/CallLinkStatus.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r159125 r159136  
     12013-08-02  Mark Hahnenberg  <mhahnenberg@apple.com>
     2
     3        CodeBlocks should be able to determine bytecode liveness
     4        https://bugs.webkit.org/show_bug.cgi?id=118546
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This will simplify some things in the DFG related to OSR exits and determining
     9        which bytecode variables are live at which points during execution. It will
     10        also be useful for making our conservative GC scan more precise. Currently it
     11        doesn't properly account for liveness while the DFG is running, so it will be
     12        off by default behing a runtime Options flag.
     13
     14        * JavaScriptCore.xcodeproj/project.pbxproj:
     15        * bytecode/BytecodeBasicBlock.cpp: Added.
     16        (JSC::isBranch): Used to determine the end of basic blocks.
     17        (JSC::isUnconditionalBranch): Used to determine when a branch at the end of a
     18        basic block can't possibly fall through to the next basic block in program order.
     19        (JSC::isTerminal): Also used to detect the end of a block.
     20        (JSC::isThrow):
     21        (JSC::isJumpTarget): Used to correctly separate basic blocks. Any jump destination
     22        must be the head of its own basic block.
     23        (JSC::linkBlocks): Links two blocks together in a bi-direcitonal fashion.
     24        (JSC::computeBytecodeBasicBlocks): Creates a set of basic blocks given a particular
     25        CodeBlock and links them together.
     26        * bytecode/BytecodeBasicBlock.h: Added.
     27        (JSC::BytecodeBasicBlock::isEntryBlock): Entry blocks are a special basic blocks
     28        that indicate the beginning of the function.
     29        (JSC::BytecodeBasicBlock::isExitBlock): Exit blocks are a special basic block that
     30        all blocks that exit the function have as a successor. Entry and exit blocks allows
     31        the various code paths to be more regular.
     32        (JSC::BytecodeBasicBlock::leaderBytecodeOffset): The leader bytecode offset is the
     33        bytecode offset of the first instruction in the block.
     34        (JSC::BytecodeBasicBlock::totalBytecodeLength): The total length of all the bytecodes
     35        in this block.
     36        (JSC::BytecodeBasicBlock::bytecodeOffsets): The bytecode offsets in this particular
     37        basic block. This Vector allows us to iterate over the bytecodes in reverse order
     38        which wouldn't be possible normally since they are of variable size.
     39        (JSC::BytecodeBasicBlock::addPredecessor): Links a block to a specified predecessor.
     40        Only creates one direction of the link.
     41        (JSC::BytecodeBasicBlock::addSuccessor): Same as addPredecessor, but for successors.
     42        (JSC::BytecodeBasicBlock::predecessors): Getter for predecessors.
     43        (JSC::BytecodeBasicBlock::successors): Getter for successors.
     44        (JSC::BytecodeBasicBlock::in): Getter for the liveness info at the head of the block.
     45        (JSC::BytecodeBasicBlock::out): Getter for the liveness info at  the tail of the block.
     46        (JSC::BytecodeBasicBlock::BytecodeBasicBlock):
     47        (JSC::BytecodeBasicBlock::addBytecodeLength): When creating basic blocks we call
     48        this function when we want to add the next bytecode in program order to this block.
     49        * bytecode/BytecodeLivenessAnalysis.cpp: Added.
     50        (JSC::BytecodeLivenessAnalysis::BytecodeLivenessAnalysis):
     51        (JSC::numberOfCapturedVariables): Convenience wrapper. Returns the
     52        number of captured variables for a particular CodeBlock, or 0 if
     53        the CodeBlock has no SymbolTable.
     54        (JSC::captureStart): Ditto, but for captureStart().
     55        (JSC::captureEnd): Ditto, but for captureEnd().
     56        (JSC::isValidRegisterForLiveness): Returns true if the liveness analysis should
     57        track the liveness of a particular operand. We ignore constants, arguments, and
     58        captured variables. We ignore arguments because they're live for the duration of
     59        a function call. We ignore captured variables because we also treat them as live
     60        for the duration of the function. This could probably be improved to be more precise,
     61        but it didn't seem worth it for now.
     62        (JSC::setForOperand): Convenience wrapper that sets the bit in the provided bit
     63        vector for the provided operand. It handles skipping over captured variables.
     64        (JSC::computeUsesForBytecodeOffset): Computes which operands are used by a particular bytecode.
     65        (JSC::computeDefsForBytecodeOffset): Computes which operands are defined by a particular
     66        bytecode. Typically this is just the left-most operand.
     67        (JSC::findBasicBlockWithLeaderOffset):
     68        (JSC::findBasicBlockForBytecodeOffset): Scans over basic blocks to find the block
     69        which contains a particular bytecode offset.
     70        (JSC::computeLocalLivenessForBytecodeOffset): Computes block-local liveness from the
     71        bottom of the block until a specified bytecode offset is reached.
     72        (JSC::computeLocalLivenessForBlock): Computes liveness for the entire block and
     73        stores the resulting liveness at the head.
     74        (JSC::BytecodeLivenessAnalysis::runLivenessFixpoint): Runs backward flow liveness
     75        analysis to fixpoint.
     76        (JSC::BytecodeLivenessAnalysis::getLivenessInfoForNonCapturedVarsAtBytecodeOffset):
     77        Slow path to get liveness info for non-captured, non-argument variable.
     78        (JSC::BytecodeLivenessAnalysis::operandIsLiveAtBytecodeOffset):
     79        (JSC::BytecodeLivenessAnalysis::getLivenessInfoAtBytecodeOffset): Returns the liveness
     80        info for both captured and non-captured vars at a particular bytecode offset.
     81        (JSC::BytecodeLivenessAnalysis::dumpResults): Dumps the output of the liveness analysis.
     82        Controlled by new flag in Options.h/.cpp.
     83        (JSC::BytecodeLivenessAnalysis::compute): Creates bytecode basic blocks and runs
     84        full liveness analysis.
     85        * bytecode/BytecodeLivenessAnalysis.h: Added.
     86        (JSC::BytecodeLivenessAnalysis::hasBeenComputed):
     87        (JSC::BytecodeLivenessAnalysis::computeIfNecessary):
     88        * bytecode/CodeBlock.cpp:
     89        (JSC::CodeBlock::CodeBlock):
     90        * bytecode/CodeBlock.h:
     91        (JSC::CodeBlock::livenessAnalysis):
     92        * bytecode/PreciseJumpTargets.cpp: Refactored to be able to get the jump targets for
     93        a particular bytecode offset for use during bytecode basic block construction.
     94        (JSC::getJumpTargetsForBytecodeOffset):
     95        (JSC::computePreciseJumpTargets):
     96        (JSC::findJumpTargetsForBytecodeOffset):
     97        * bytecode/PreciseJumpTargets.h:
     98        * runtime/Options.cpp:
     99        (JSC::Options::initialize):
     100        * runtime/Options.h:
     101
    11022013-11-11  Andy Estes  <aestes@apple.com>
    2103
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r159031 r159136  
    101101        Source/JavaScriptCore/bytecode/ArrayProfile.h \
    102102        Source/JavaScriptCore/bytecode/ByValInfo.h \
     103    Source/JavaScriptCore/bytecode/BytecodeBasicBlock.cpp \
     104    Source/JavaScriptCore/bytecode/BytecodeBasicBlock.h \
     105    Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp \
     106    Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.h \
    103107        Source/JavaScriptCore/bytecode/BytecodeConventions.h \
    104108        Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r159031 r159136  
    297297    <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp" />
    298298    <ClCompile Include="..\bytecode\ArrayProfile.cpp" />
     299    <ClCompile Include="..\bytecode\BytecodeBasicBlock.cpp" />
     300    <ClCompile Include="..\bytecode\BytecodeLivenessAnalysis.cpp" />
    299301    <ClCompile Include="..\bytecode\CallLinkInfo.cpp" />
    300302    <ClCompile Include="..\bytecode\CallLinkStatus.cpp" />
     
    742744    <ClInclude Include="..\bytecode\ArrayProfile.h" />
    743745    <ClInclude Include="..\bytecode\ByValInfo.h" />
     746    <ClInclude Include="..\bytecode\BytecodeBasicBlock.h" />
     747    <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h" />
    744748    <ClInclude Include="..\bytecode\CallLinkInfo.h" />
    745749    <ClInclude Include="..\bytecode\CallLinkStatus.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r159031 r159136  
    109109      <Filter>bytecode</Filter>
    110110    </ClCompile>
     111    <ClCompile Include="..\bytecode\BytecodeBasicBlock.cpp">
     112      <Filter>bytecode</Filter>
     113    </ClCompile>
     114    <ClCompile Include="..\bytecode\BytecodeLivenessAnalysis.cpp">
     115      <Filter>bytecode</Filter>
     116    </ClCompile>
    111117    <ClCompile Include="..\bytecode\CallLinkInfo.cpp">
    112118      <Filter>bytecode</Filter>
     
    13631369    </ClInclude>
    13641370    <ClInclude Include="..\bytecode\ByValInfo.h">
     1371      <Filter>bytecode</Filter>
     1372    </ClInclude>
     1373    <ClInclude Include="..\bytecode\BytecodeBasicBlock.h">
     1374      <Filter>bytecode</Filter>
     1375    </ClInclude>
     1376    <ClInclude Include="..\bytecode\BytecodeLivenessAnalysis.h">
    13651377      <Filter>bytecode</Filter>
    13661378    </ClInclude>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r159031 r159136  
    12171217                C2F0F2D116BAEEE900187C19 /* StructureRareData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */; };
    12181218                C2FC9BD316644DFB00810D33 /* CopiedBlockInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FC9BD216644DFB00810D33 /* CopiedBlockInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1219                C2FCAE1017A9C24E0034C735 /* BytecodeBasicBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */; };
     1220                C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */; };
     1221                C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */; };
     1222                C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */; };
    12191223                C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */ = {isa = PBXBuildFile; fileRef = C2FE18A316BAEC4000AF3061 /* StructureRareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12201224                DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = DDF7ABD211F60ED200108E36 /* GCActivityCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    25032507                C2F0F2D016BAEEE900187C19 /* StructureRareData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureRareData.cpp; sourceTree = "<group>"; };
    25042508                C2FC9BD216644DFB00810D33 /* CopiedBlockInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedBlockInlines.h; sourceTree = "<group>"; };
     2509                C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeBasicBlock.cpp; sourceTree = "<group>"; };
     2510                C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeBasicBlock.h; sourceTree = "<group>"; };
     2511                C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BytecodeLivenessAnalysis.cpp; sourceTree = "<group>"; };
     2512                C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeLivenessAnalysis.h; sourceTree = "<group>"; };
    25052513                C2FE18A316BAEC4000AF3061 /* StructureRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureRareData.h; sourceTree = "<group>"; };
    25062514                D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; };
     
    40244032                        isa = PBXGroup;
    40254033                        children = (
     4034                                C2FCAE0C17A9C24E0034C735 /* BytecodeBasicBlock.cpp */,
     4035                                C2FCAE0D17A9C24E0034C735 /* BytecodeBasicBlock.h */,
     4036                                C2FCAE0E17A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp */,
     4037                                C2FCAE0F17A9C24E0034C735 /* BytecodeLivenessAnalysis.h */,
    40264038                                0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */,
    40274039                                0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */,
     
    41624174                                BC18C3E60E16F5CD00B34460 /* ArrayConstructor.h in Headers */,
    41634175                                0FB7F39515ED8E4600F167B2 /* ArrayConventions.h in Headers */,
     4176                                C2FCAE1117A9C24E0034C735 /* BytecodeBasicBlock.h in Headers */,
    41644177                                A7BDAEC717F4EA1400F6140C /* ArrayIteratorConstructor.h in Headers */,
    41654178                                A7BDAEC917F4EA1400F6140C /* ArrayIteratorPrototype.h in Headers */,
     
    47524765                                BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */,
    47534766                                BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */,
     4767                                C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */,
    47544768                                BC18C46A0E16F5CD00B34460 /* StringPrototype.h in Headers */,
    47554769                                142E313B134FF0A600AFADB5 /* Strong.h in Headers */,
     
    52885302                                147F39C5107EC37600427A48 /* DateInstance.cpp in Sources */,
    52895303                                147F39C6107EC37600427A48 /* DatePrototype.cpp in Sources */,
     5304                                C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */,
    52905305                                14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */,
    52915306                                BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */,
     
    56075622                                0FF729B3166AD35C000F5BA3 /* ProfilerOrigin.cpp in Sources */,
    56085623                                0FF729B4166AD35C000F5BA3 /* ProfilerOriginStack.cpp in Sources */,
     5624                                C2FCAE1017A9C24E0034C735 /* BytecodeBasicBlock.cpp in Sources */,
    56095625                                0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
    56105626                                0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r159097 r159136  
    15731573    , m_reoptimizationRetryCounter(0)
    15741574    , m_hash(other.m_hash)
     1575    , m_livenessAnalysis(other.m_livenessAnalysis)
    15751576#if ENABLE(JIT)
    15761577    , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
     
    16181619    , m_optimizationDelayCounter(0)
    16191620    , m_reoptimizationRetryCounter(0)
     1621    , m_livenessAnalysis(this)
    16201622#if ENABLE(JIT)
    16211623    , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
     
    19201922    if (Options::dumpGeneratedBytecodes())
    19211923        dumpBytecode();
     1924
    19221925    m_heap->m_codeBlocks.add(this);
    19231926    m_heap->reportExtraMemoryCost(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r159097 r159136  
    3434#include "ByValInfo.h"
    3535#include "BytecodeConventions.h"
     36#include "BytecodeLivenessAnalysis.h"
    3637#include "CallLinkInfo.h"
    3738#include "CallReturnOffsetToBytecodeOffset.h"
     
    9697class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFinalizer, public WeakReferenceHarvester {
    9798    WTF_MAKE_FAST_ALLOCATED;
     99    friend class BytecodeLivenessAnalysis;
    98100    friend class JIT;
    99101    friend class LLIntOffsetsExtractor;
     
    677679
    678680    JSGlobalObject* globalObjectFor(CodeOrigin);
     681
     682    BytecodeLivenessAnalysis& livenessAnalysis() { return m_livenessAnalysis; }
    679683
    680684    // Jump Tables
     
    10741078    mutable CodeBlockHash m_hash;
    10751079
     1080    BytecodeLivenessAnalysis m_livenessAnalysis;
     1081
    10761082    struct RareData {
    10771083        WTF_MAKE_FAST_ALLOCATED;
  • trunk/Source/JavaScriptCore/bytecode/PreciseJumpTargets.cpp

    r153237 r159136  
    2929namespace JSC {
    3030
     31template <size_t vectorSize>
     32static void getJumpTargetsForBytecodeOffset(CodeBlock* codeBlock, Interpreter* interpreter, Instruction* instructionsBegin, unsigned bytecodeOffset, Vector<unsigned, vectorSize>& out)
     33{
     34    OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode);
     35    Instruction* current = instructionsBegin + bytecodeOffset;
     36    switch (opcodeID) {
     37    case op_jmp:
     38        out.append(bytecodeOffset + current[1].u.operand);
     39        break;
     40    case op_jtrue:
     41    case op_jfalse:
     42    case op_jeq_null:
     43    case op_jneq_null:
     44        out.append(bytecodeOffset + current[2].u.operand);
     45        break;
     46    case op_jneq_ptr:
     47    case op_jless:
     48    case op_jlesseq:
     49    case op_jgreater:
     50    case op_jgreatereq:
     51    case op_jnless:
     52    case op_jnlesseq:
     53    case op_jngreater:
     54    case op_jngreatereq:
     55        out.append(bytecodeOffset + current[3].u.operand);
     56        break;
     57    case op_switch_imm:
     58    case op_switch_char: {
     59        SimpleJumpTable& table = codeBlock->switchJumpTable(current[1].u.operand);
     60        for (unsigned i = table.branchOffsets.size(); i--;)
     61            out.append(bytecodeOffset + table.branchOffsets[i]);
     62        out.append(bytecodeOffset + current[2].u.operand);
     63        break;
     64    }
     65    case op_switch_string: {
     66        StringJumpTable& table = codeBlock->stringSwitchJumpTable(current[1].u.operand);
     67        StringJumpTable::StringOffsetTable::iterator iter = table.offsetTable.begin();
     68        StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
     69        for (; iter != end; ++iter)
     70            out.append(bytecodeOffset + iter->value.branchOffset);
     71        out.append(bytecodeOffset + current[2].u.operand);
     72        break;
     73    }
     74    case op_get_pnames:
     75        out.append(bytecodeOffset + current[5].u.operand);
     76        break;
     77    case op_next_pname:
     78        out.append(bytecodeOffset + current[6].u.operand);
     79        break;
     80    case op_check_has_instance:
     81        out.append(bytecodeOffset + current[4].u.operand);
     82        break;
     83    case op_loop_hint:
     84        out.append(bytecodeOffset);
     85        break;
     86    default:
     87        break;
     88    }
     89}
     90
    3191void computePreciseJumpTargets(CodeBlock* codeBlock, Vector<unsigned, 32>& out)
    3292{
     
    46106    for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount;) {
    47107        OpcodeID opcodeID = interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode);
    48         Instruction* current = instructionsBegin + bytecodeOffset;
    49         switch (opcodeID) {
    50         case op_jmp:
    51             out.append(bytecodeOffset + current[1].u.operand);
    52             break;
    53         case op_jtrue:
    54         case op_jfalse:
    55         case op_jeq_null:
    56         case op_jneq_null:
    57             out.append(bytecodeOffset + current[2].u.operand);
    58             break;
    59         case op_jneq_ptr:
    60         case op_jless:
    61         case op_jlesseq:
    62         case op_jgreater:
    63         case op_jgreatereq:
    64         case op_jnless:
    65         case op_jnlesseq:
    66         case op_jngreater:
    67         case op_jngreatereq:
    68             out.append(bytecodeOffset + current[3].u.operand);
    69             break;
    70         case op_switch_imm:
    71         case op_switch_char: {
    72             SimpleJumpTable& table = codeBlock->switchJumpTable(current[1].u.operand);
    73             for (unsigned i = table.branchOffsets.size(); i--;)
    74                 out.append(bytecodeOffset + table.branchOffsets[i]);
    75             out.append(bytecodeOffset + current[2].u.operand);
    76             break;
    77         }
    78         case op_switch_string: {
    79             StringJumpTable& table = codeBlock->stringSwitchJumpTable(current[1].u.operand);
    80             StringJumpTable::StringOffsetTable::iterator iter = table.offsetTable.begin();
    81             StringJumpTable::StringOffsetTable::iterator end = table.offsetTable.end();
    82             for (; iter != end; ++iter)
    83                 out.append(bytecodeOffset + iter->value.branchOffset);
    84             out.append(bytecodeOffset + current[2].u.operand);
    85             break;
    86         }
    87         case op_get_pnames:
    88             out.append(bytecodeOffset + current[5].u.operand);
    89             break;
    90         case op_next_pname:
    91             out.append(bytecodeOffset + current[6].u.operand);
    92             break;
    93         case op_check_has_instance:
    94             out.append(bytecodeOffset + current[4].u.operand);
    95             break;
    96         case op_loop_hint:
    97             out.append(bytecodeOffset);
    98             break;
    99         default:
    100             break;
    101         }
     108        getJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, out);
    102109        bytecodeOffset += opcodeLengths[opcodeID];
    103110    }
     
    119126}
    120127
     128void findJumpTargetsForBytecodeOffset(CodeBlock* codeBlock, unsigned bytecodeOffset, Vector<unsigned, 1>& out)
     129{
     130    Interpreter* interpreter = codeBlock->vm()->interpreter;
     131    Instruction* instructionsBegin = codeBlock->instructions().begin();
     132    getJumpTargetsForBytecodeOffset(codeBlock, interpreter, instructionsBegin, bytecodeOffset, out);
     133}
     134
    121135} // namespace JSC
    122136
  • trunk/Source/JavaScriptCore/bytecode/PreciseJumpTargets.h

    r141931 r159136  
    3232
    3333void computePreciseJumpTargets(CodeBlock*, Vector<unsigned, 32>& out);
     34void findJumpTargetsForBytecodeOffset(CodeBlock*, unsigned bytecodeOffset, Vector<unsigned, 1>& out);
    3435
    3536} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Options.cpp

    r153175 r159136  
    213213    useRegExpJIT() = false;
    214214#endif
    215    
     215
    216216    // Do range checks where needed and make corrections to the options:
    217217    ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp());
  • trunk/Source/JavaScriptCore/runtime/Options.h

    r158535 r159136  
    100100    \
    101101    v(bool, dumpGeneratedBytecodes, false) \
     102    v(bool, dumpBytecodeLivenessResults, false) \
    102103    \
    103104    /* showDisassembly implies showDFGDisassembly. */ \
  • trunk/Source/WTF/wtf/FastBitVector.h

    r156792 r159136  
    2727#define FastBitVector_h
    2828
     29#include <string.h>
    2930#include <wtf/FastMalloc.h>
    3031#include <wtf/StdLibExtras.h>
Note: See TracChangeset for help on using the changeset viewer.