Changeset 209974 in webkit


Ignore:
Timestamp:
Dec 18, 2016 11:04:20 AM (7 years ago)
Author:
mark.lam@apple.com
Message:

Rename finallyActionRegister to completionTypeRegister and only store int JSValues in it.
https://bugs.webkit.org/show_bug.cgi?id=165979

Reviewed by Saam Barati.

This patch makes it so that we only store int JSValues in the finallyActionRegister
thereby making type prediction on this register more successful for JITs. In so
doing, we are able to get some additional benefits:

  1. Renamed the following: FinallyRegistersScope => CompletionRecordScope finallyActionRegister => completionTypeRegister finallyReturnValueRegister => completionValueRegister

These new names are more in line with the ES spec, which describes these
values as the completion record and its type and value properties.
https://tc39.github.io/ecma262/#sec-completion-record-specification-type

  1. We now think of the Break and Continue jumpIDs as encodings of CompletionType (in our implementation of completion type). As a result, we only need one of each of the emitter methods for getting, setting, and compare-and-jump on the completion type. The code using these methods also reads much clearer now.
  1. Finally blocks' op_catch should now always pop the caught Exception object into the completionValueRegister instead of the completionTypeRegister (formerly finallyActionRegister).

Also removed the restoreScopeRegister() call in the IteratorClose catch block
because that is an implementation specific synthesized catch block, and we
can guarantee that it never needs to resolve any symbols from the scope. Hence,
there is no need to restore the scope register.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitEnumeration):
(JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded):
(JSC::BytecodeGenerator::emitReturnViaFinallyIfNeeded):
(JSC::BytecodeGenerator::emitFinallyCompletion):
(JSC::BytecodeGenerator::allocateCompletionRecordRegisters):
(JSC::BytecodeGenerator::releaseCompletionRecordRegisters):
(JSC::BytecodeGenerator::emitJumpIfCompletionType):
(JSC::BytecodeGenerator::allocateFinallyRegisters): Deleted.
(JSC::BytecodeGenerator::releaseFinallyRegisters): Deleted.
(JSC::BytecodeGenerator::emitCompareFinallyActionAndJumpIf): Deleted.

  • bytecompiler/BytecodeGenerator.h:

(JSC::bytecodeOffsetToJumpID):
(JSC::FinallyJump::FinallyJump):
(JSC::FinallyContext::registerJump):
(JSC::BytecodeGenerator::CompletionRecordScope::CompletionRecordScope):
(JSC::BytecodeGenerator::CompletionRecordScope::~CompletionRecordScope):
(JSC::BytecodeGenerator::completionTypeRegister):
(JSC::BytecodeGenerator::completionValueRegister):
(JSC::BytecodeGenerator::emitSetCompletionType):
(JSC::BytecodeGenerator::emitSetCompletionValue):
(JSC::BytecodeGenerator::FinallyRegistersScope::FinallyRegistersScope): Deleted.
(JSC::BytecodeGenerator::FinallyRegistersScope::~FinallyRegistersScope): Deleted.
(JSC::BytecodeGenerator::finallyActionRegister): Deleted.
(JSC::BytecodeGenerator::finallyReturnValueRegister): Deleted.
(JSC::BytecodeGenerator::emitSetFinallyActionToNormalCompletion): Deleted.
(JSC::BytecodeGenerator::emitSetFinallyActionToReturnCompletion): Deleted.
(JSC::BytecodeGenerator::emitSetFinallyActionToJumpID): Deleted.
(JSC::BytecodeGenerator::emitSetFinallyReturnValueRegister): Deleted.
(JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNormalCompletion): Deleted.
(JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotJump): Deleted.
(JSC::BytecodeGenerator::emitJumpIfFinallyActionIsReturnCompletion): Deleted.
(JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotReturnCompletion): Deleted.
(JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotThrowCompletion): Deleted.
(JSC::BytecodeGenerator::emitJumpIfCompletionTypeIsThrow): Deleted.
(JSC::BytecodeGenerator::bytecodeOffsetToJumpID): Deleted.

  • bytecompiler/NodesCodegen.cpp:

(JSC::TryNode::emitBytecode):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r209966 r209974  
     12016-12-18  Mark Lam  <mark.lam@apple.com>
     2
     3        Rename finallyActionRegister to completionTypeRegister and only store int JSValues in it.
     4        https://bugs.webkit.org/show_bug.cgi?id=165979
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch makes it so that we only store int JSValues in the finallyActionRegister
     9        thereby making type prediction on this register more successful for JITs.  In so
     10        doing, we are able to get some additional benefits:
     11
     12        1. Renamed the following:
     13           FinallyRegistersScope => CompletionRecordScope
     14           finallyActionRegister => completionTypeRegister
     15           finallyReturnValueRegister => completionValueRegister
     16
     17           These new names are more in line with the ES spec, which describes these
     18           values as the completion record and its type and value properties.
     19           https://tc39.github.io/ecma262/#sec-completion-record-specification-type
     20
     21        2. We now think of the Break and Continue jumpIDs as encodings of CompletionType
     22           (in our implementation of completion type).  As a result, we only need one of
     23           each of the emitter methods for getting, setting, and compare-and-jump on the
     24           completion type.  The code using these methods also reads much clearer now. 
     25
     26        3. Finally blocks' op_catch should now always pop the caught Exception object into
     27           the completionValueRegister instead of the completionTypeRegister (formerly
     28           finallyActionRegister).
     29
     30        Also removed the restoreScopeRegister() call in the IteratorClose catch block
     31        because that is an implementation specific synthesized catch block, and we
     32        can guarantee that it never needs to resolve any symbols from the scope.  Hence,
     33        there is no need to restore the scope register.
     34
     35        * bytecompiler/BytecodeGenerator.cpp:
     36        (JSC::BytecodeGenerator::emitEnumeration):
     37        (JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded):
     38        (JSC::BytecodeGenerator::emitReturnViaFinallyIfNeeded):
     39        (JSC::BytecodeGenerator::emitFinallyCompletion):
     40        (JSC::BytecodeGenerator::allocateCompletionRecordRegisters):
     41        (JSC::BytecodeGenerator::releaseCompletionRecordRegisters):
     42        (JSC::BytecodeGenerator::emitJumpIfCompletionType):
     43        (JSC::BytecodeGenerator::allocateFinallyRegisters): Deleted.
     44        (JSC::BytecodeGenerator::releaseFinallyRegisters): Deleted.
     45        (JSC::BytecodeGenerator::emitCompareFinallyActionAndJumpIf): Deleted.
     46        * bytecompiler/BytecodeGenerator.h:
     47        (JSC::bytecodeOffsetToJumpID):
     48        (JSC::FinallyJump::FinallyJump):
     49        (JSC::FinallyContext::registerJump):
     50        (JSC::BytecodeGenerator::CompletionRecordScope::CompletionRecordScope):
     51        (JSC::BytecodeGenerator::CompletionRecordScope::~CompletionRecordScope):
     52        (JSC::BytecodeGenerator::completionTypeRegister):
     53        (JSC::BytecodeGenerator::completionValueRegister):
     54        (JSC::BytecodeGenerator::emitSetCompletionType):
     55        (JSC::BytecodeGenerator::emitSetCompletionValue):
     56        (JSC::BytecodeGenerator::FinallyRegistersScope::FinallyRegistersScope): Deleted.
     57        (JSC::BytecodeGenerator::FinallyRegistersScope::~FinallyRegistersScope): Deleted.
     58        (JSC::BytecodeGenerator::finallyActionRegister): Deleted.
     59        (JSC::BytecodeGenerator::finallyReturnValueRegister): Deleted.
     60        (JSC::BytecodeGenerator::emitSetFinallyActionToNormalCompletion): Deleted.
     61        (JSC::BytecodeGenerator::emitSetFinallyActionToReturnCompletion): Deleted.
     62        (JSC::BytecodeGenerator::emitSetFinallyActionToJumpID): Deleted.
     63        (JSC::BytecodeGenerator::emitSetFinallyReturnValueRegister): Deleted.
     64        (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNormalCompletion): Deleted.
     65        (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotJump): Deleted.
     66        (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsReturnCompletion): Deleted.
     67        (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotReturnCompletion): Deleted.
     68        (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotThrowCompletion): Deleted.
     69        (JSC::BytecodeGenerator::emitJumpIfCompletionTypeIsThrow): Deleted.
     70        (JSC::BytecodeGenerator::bytecodeOffsetToJumpID): Deleted.
     71        * bytecompiler/NodesCodegen.cpp:
     72        (JSC::TryNode::emitBytecode):
     73
    1742016-12-17  Saam Barati  <sbarati@apple.com>
    275
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r209956 r209974  
    41274127void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack, ForOfNode* forLoopNode, RegisterID* forLoopSymbolTable)
    41284128{
    4129     FinallyRegistersScope finallyRegistersScope(*this);
     4129    CompletionRecordScope completionRecordScope(*this);
    41304130
    41314131    RefPtr<RegisterID> subject = newTemporary();
     
    41704170            popTry(tryData, finallyViaThrowLabel.get());
    41714171
     4172            RefPtr<Label> finallyBodyLabel = newLabel();
     4173            RefPtr<RegisterID> finallyExceptionRegister = newTemporary();
    41724174            RegisterID* unused = newTemporary();
    4173             emitCatch(finallyActionRegister(), unused);
    4174             // Setting the finallyActionRegister to the caught exception here implies CompletionType::Throw.
     4175
     4176            emitCatch(completionValueRegister(), unused);
     4177            emitSetCompletionType(CompletionType::Throw);
     4178            emitMove(finallyExceptionRegister.get(), completionValueRegister());
     4179            emitJump(finallyBodyLabel.get());
    41754180
    41764181            emitLabel(finallyLabel.get());
     4182            emitMoveEmptyValue(finallyExceptionRegister.get());
     4183
     4184            emitLabel(finallyBodyLabel.get());
    41774185            restoreScopeRegister();
    41784186
     
    41814189            RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
    41824190            emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), finallyDone.get());
    4183 
    4184             RefPtr<RegisterID> originalFinallyActionRegister = newTemporary();
    4185             emitMove(originalFinallyActionRegister.get(), finallyActionRegister());
    41864191
    41874192            RefPtr<Label> returnCallTryStart = newLabel();
     
    42104215                RegisterID* unused = newTemporary();
    42114216                emitCatch(exceptionRegister.get(), unused);
    4212                 restoreScopeRegister();
     4217                // Since this is a synthesized catch block and we're guaranteed to never need
     4218                // to resolve any symbols from the scope, we can skip restoring the scope
     4219                // register here.
    42134220
    42144221                RefPtr<Label> throwLabel = newLabel();
    4215                 emitJumpIfCompletionTypeIsThrow(originalFinallyActionRegister.get(), throwLabel.get());
    4216                 emitMove(originalFinallyActionRegister.get(), exceptionRegister.get());
     4222                emitJumpIfTrue(emitIsEmpty(newTemporary(), finallyExceptionRegister.get()), throwLabel.get());
     4223                emitMove(exceptionRegister.get(), finallyExceptionRegister.get());
    42174224
    42184225                emitLabel(throwLabel.get());
    4219                 emitThrow(originalFinallyActionRegister.get());
     4226                emitThrow(exceptionRegister.get());
    42204227
    42214228                emitLabel(endCatchLabel.get());
     
    48204827        return false; // No finallys to thread through.
    48214828
    4822     int jumpID = bytecodeOffsetToJumpID(instructions().size());
     4829    auto jumpID = bytecodeOffsetToJumpID(instructions().size());
    48234830    int lexicalScopeIndex = labelScopeDepthToLexicalScopeIndex(targetLabelScopeDepth);
    48244831    outermostFinallyContext->registerJump(jumpID, lexicalScopeIndex, jumpTarget);
    48254832
    4826     emitSetFinallyActionToJumpID(jumpID);
     4833    emitSetCompletionType(jumpID);
    48274834    emitJump(innermostFinallyContext->finallyLabel());
    48284835    return true; // We'll be jumping to a finally block.
     
    48504857        return false; // No finallys to thread through.
    48514858
    4852     emitSetFinallyActionToReturnCompletion();
    4853     emitSetFinallyReturnValueRegister(returnRegister);
     4859    emitSetCompletionType(CompletionType::Return);
     4860    emitSetCompletionValue(returnRegister);
    48544861    emitJump(innermostFinallyContext->finallyLabel());
    48554862    return true; // We'll be jumping to a finally block.
     
    48584865void BytecodeGenerator::emitFinallyCompletion(FinallyContext& context, Label* normalCompletionLabel)
    48594866{
    4860     // FIXME: switch the finallyActionRegister to only store int values for all CompletionTypes. This is more optimal for JIT type speculation.
    4861     // https://bugs.webkit.org/show_bug.cgi?id=165979
    4862     emitJumpIfFinallyActionIsNormalCompletion(normalCompletionLabel);
     4867    emitJumpIfCompletionType(op_stricteq, CompletionType::Normal, normalCompletionLabel);
    48634868
    48644869    if (context.numberOfBreaksOrContinues() || context.handlesReturns()) {
     
    48704875                RefPtr<Label> nextLabel = newLabel();
    48714876                auto& jump = context.jumps(i);
    4872                 emitJumpIfFinallyActionIsNotJump(jump.jumpID, nextLabel.get());
     4877                emitJumpIfCompletionType(op_nstricteq, jump.jumpID, nextLabel.get());
    48734878
    48744879                restoreScopeRegister(jump.targetLexicalScopeIndex);
    4875                 emitSetFinallyActionToNormalCompletion();
     4880                emitSetCompletionType(CompletionType::Normal);
    48764881                emitJump(jump.targetLabel.get());
    48774882
     
    48814886            bool hasBreaksOrContinuesNotCoveredByJumps = context.numberOfBreaksOrContinues() > numberOfJumps;
    48824887            if (hasBreaksOrContinuesNotCoveredByJumps || context.handlesReturns())
    4883                 emitJumpIfFinallyActionIsNotThrowCompletion(outerContext->finallyLabel());
     4888                emitJumpIfCompletionType(op_nstricteq, CompletionType::Throw, outerContext->finallyLabel());
    48844889
    48854890        } else {
     
    48914896                RefPtr<Label> nextLabel = newLabel();
    48924897                auto& jump = context.jumps(i);
    4893                 emitJumpIfFinallyActionIsNotJump(jump.jumpID, nextLabel.get());
     4898                emitJumpIfCompletionType(op_nstricteq, jump.jumpID, nextLabel.get());
    48944899
    48954900                restoreScopeRegister(jump.targetLexicalScopeIndex);
    4896                 emitSetFinallyActionToNormalCompletion();
     4901                emitSetCompletionType(CompletionType::Normal);
    48974902                emitJump(jump.targetLabel.get());
    48984903
     
    49024907            if (context.handlesReturns()) {
    49034908                RefPtr<Label> notReturnLabel = newLabel();
    4904                 emitJumpIfFinallyActionIsNotReturnCompletion(notReturnLabel.get());
     4909                emitJumpIfCompletionType(op_nstricteq, CompletionType::Return, notReturnLabel.get());
    49054910
    49064911                emitWillLeaveCallFrameDebugHook();
    4907                 emitReturn(finallyReturnValueRegister(), ReturnFrom::Finally);
     4912                emitReturn(completionValueRegister(), ReturnFrom::Finally);
    49084913               
    49094914                emitLabel(notReturnLabel.get());
     
    49114916        }
    49124917    }
    4913     emitThrow(finallyActionRegister());
    4914 }
    4915 
    4916 bool BytecodeGenerator::allocateFinallyRegisters()
    4917 {
    4918     if (m_finallyActionRegister)
     4918    emitThrow(completionValueRegister());
     4919}
     4920
     4921bool BytecodeGenerator::allocateCompletionRecordRegisters()
     4922{
     4923    if (m_completionTypeRegister)
    49194924        return false;
    49204925
    4921     ASSERT(!m_finallyReturnValueRegister);
    4922     m_finallyActionRegister = newTemporary();
    4923     m_finallyReturnValueRegister = newTemporary();
    4924 
    4925     emitSetFinallyActionToNormalCompletion();
    4926     emitMoveEmptyValue(m_finallyReturnValueRegister.get());
     4926    ASSERT(!m_completionValueRegister);
     4927    m_completionTypeRegister = newTemporary();
     4928    m_completionValueRegister = newTemporary();
     4929
     4930    emitSetCompletionType(CompletionType::Normal);
     4931    emitMoveEmptyValue(m_completionValueRegister.get());
    49274932    return true;
    49284933}
    49294934
    4930 void BytecodeGenerator::releaseFinallyRegisters()
    4931 {
    4932     ASSERT(m_finallyActionRegister && m_finallyReturnValueRegister);
    4933     m_finallyActionRegister = nullptr;
    4934     m_finallyReturnValueRegister = nullptr;
    4935 }
    4936 
    4937 void BytecodeGenerator::emitCompareFinallyActionAndJumpIf(OpcodeID compareOpcode, int value, Label* jumpTarget)
     4935void BytecodeGenerator::releaseCompletionRecordRegisters()
     4936{
     4937    ASSERT(m_completionTypeRegister && m_completionValueRegister);
     4938    m_completionTypeRegister = nullptr;
     4939    m_completionValueRegister = nullptr;
     4940}
     4941
     4942void BytecodeGenerator::emitJumpIfCompletionType(OpcodeID compareOpcode, CompletionType type, Label* jumpTarget)
    49384943{
    49394944    RefPtr<RegisterID> tempRegister = newTemporary();
    4940     RegisterID* valueConstant = addConstantValue(JSValue(value));
     4945    RegisterID* valueConstant = addConstantValue(JSValue(static_cast<int>(type)));
    49414946    OperandTypes operandTypes = OperandTypes(ResultType::numberTypeIsInt32(), ResultType::unknownType());
    49424947
    4943     auto equivalenceResult = emitBinaryOp(compareOpcode, tempRegister.get(), valueConstant, finallyActionRegister(), operandTypes);
     4948    auto equivalenceResult = emitBinaryOp(compareOpcode, tempRegister.get(), valueConstant, completionTypeRegister(), operandTypes);
    49444949    emitJumpIfTrue(equivalenceResult, jumpTarget);
    49454950}
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r209952 r209974  
    8181    };
    8282
     83    // https://tc39.github.io/ecma262/#sec-completion-record-specification-type
     84    //
     85    // For the Break and Continue cases, instead of using the Break and Continue enum values
     86    // below, we use the unique jumpID of the break and continue statement as the encoding
     87    // for the CompletionType value. emitFinallyCompletion() uses this jumpID value later
     88    // to determine the appropriate jump target to jump to after executing the relevant finally
     89    // blocks. The jumpID is computed as:
     90    //     jumpID = bytecodeOffset (of the break/continue node) + CompletionType::NumberOfTypes.
     91    // Hence, there won't be any collision between jumpIDs and CompletionType enums.
     92    enum class CompletionType : int {
     93        Normal,
     94        Break,
     95        Continue,
     96        Return,
     97        Throw,
     98       
     99        NumberOfTypes
     100    };
     101
     102    inline CompletionType bytecodeOffsetToJumpID(unsigned offset)
     103    {
     104        int jumpIDAsInt = offset + static_cast<int>(CompletionType::NumberOfTypes);
     105        ASSERT(jumpIDAsInt >= static_cast<int>(CompletionType::NumberOfTypes));
     106        return static_cast<CompletionType>(jumpIDAsInt);
     107    }
     108
    83109    struct FinallyJump {
    84         FinallyJump(int jumpID, int targetLexicalScopeIndex, Label* targetLabel)
     110        FinallyJump(CompletionType jumpID, int targetLexicalScopeIndex, Label* targetLabel)
    85111            : jumpID(jumpID)
    86112            , targetLexicalScopeIndex(targetLexicalScopeIndex)
     
    88114        { }
    89115
    90         int jumpID { 0 };
    91         int targetLexicalScopeIndex { 0 };
     116        CompletionType jumpID;
     117        int targetLexicalScopeIndex;
    92118        RefPtr<Label> targetLabel;
    93119    };
     
    117143        void setHandlesReturns() { m_handlesReturns = true; }
    118144
    119         void registerJump(int jumpID, int lexicalScopeIndex, Label* targetLabel)
     145        void registerJump(CompletionType jumpID, int lexicalScopeIndex, Label* targetLabel)
    120146        {
    121147            if (!m_jumps)
     
    776802        void emitWillLeaveCallFrameDebugHook();
    777803
    778         class FinallyRegistersScope {
     804        class CompletionRecordScope {
    779805        public:
    780             FinallyRegistersScope(BytecodeGenerator& generator, bool needFinallyRegisters = true)
     806            CompletionRecordScope(BytecodeGenerator& generator, bool needCompletionRecordRegisters = true)
    781807                : m_generator(generator)
    782808            {
    783                 if (needFinallyRegisters && m_generator.allocateFinallyRegisters())
     809                if (needCompletionRecordRegisters && m_generator.allocateCompletionRecordRegisters())
    784810                    m_needToReleaseOnDestruction = true;
    785811            }
    786             ~FinallyRegistersScope()
     812            ~CompletionRecordScope()
    787813            {
    788814                if (m_needToReleaseOnDestruction)
    789                     m_generator.releaseFinallyRegisters();
     815                    m_generator.releaseCompletionRecordRegisters();
    790816            }
    791817
     
    795821        };
    796822
    797         RegisterID* finallyActionRegister() const
    798         {
    799             ASSERT(m_finallyActionRegister);
    800             return m_finallyActionRegister.get();
    801         }
    802         RegisterID* finallyReturnValueRegister() const
    803         {
    804             ASSERT(m_finallyReturnValueRegister);
    805             return m_finallyReturnValueRegister.get();
    806         }
    807 
    808         void emitSetFinallyActionToNormalCompletion()
    809         {
    810             emitMoveEmptyValue(m_finallyActionRegister.get());
    811         }
    812         void emitSetFinallyActionToReturnCompletion()
    813         {
    814             emitLoad(finallyActionRegister(), JSValue(static_cast<int>(CompletionType::Return)));
    815         }
    816         void emitSetFinallyActionToJumpID(int jumpID)
    817         {
    818             emitLoad(finallyActionRegister(), JSValue(jumpID));
    819         }
    820         void emitSetFinallyReturnValueRegister(RegisterID* reg)
    821         {
    822             emitMove(finallyReturnValueRegister(), reg);
    823         }
    824 
    825         void emitJumpIfFinallyActionIsNormalCompletion(Label* jumpTarget)
    826         {
    827             emitJumpIfTrue(emitIsEmpty(newTemporary(), finallyActionRegister()), jumpTarget);
    828         }
    829 
    830         void emitJumpIfFinallyActionIsNotJump(int jumpID, Label* jumpTarget)
    831         {
    832             emitCompareFinallyActionAndJumpIf(op_nstricteq, jumpID, jumpTarget);
    833         }
    834 
    835         void emitJumpIfFinallyActionIsReturnCompletion(Label* jumpTarget)
    836         {
    837             emitCompareFinallyActionAndJumpIf(op_stricteq, static_cast<int>(CompletionType::Return), jumpTarget);
    838         }
    839         void emitJumpIfFinallyActionIsNotReturnCompletion(Label* jumpTarget)
    840         {
    841             emitCompareFinallyActionAndJumpIf(op_nstricteq, static_cast<int>(CompletionType::Return), jumpTarget);
    842         }
    843 
    844         void emitJumpIfFinallyActionIsNotThrowCompletion(Label* jumpTarget)
    845         {
    846             emitJumpIfTrue(emitIsNumber(newTemporary(), finallyActionRegister()), jumpTarget);
    847         }
    848         void emitJumpIfCompletionTypeIsThrow(RegisterID* reg, Label* jumpTarget)
    849         {
    850             emitJumpIfFalse(emitIsNumber(newTemporary(), reg), jumpTarget);
    851         }
     823        RegisterID* completionTypeRegister() const
     824        {
     825            ASSERT(m_completionTypeRegister);
     826            return m_completionTypeRegister.get();
     827        }
     828        RegisterID* completionValueRegister() const
     829        {
     830            ASSERT(m_completionValueRegister);
     831            return m_completionValueRegister.get();
     832        }
     833
     834        void emitSetCompletionType(CompletionType type)
     835        {
     836            emitLoad(completionTypeRegister(), JSValue(static_cast<int>(type)));
     837        }
     838        void emitSetCompletionValue(RegisterID* reg)
     839        {
     840            emitMove(completionValueRegister(), reg);
     841        }
     842
     843        void emitJumpIfCompletionType(OpcodeID compareOpcode, CompletionType, Label* jumpTarget);
    852844
    853845        bool emitJumpViaFinallyIfNeeded(int targetLabelScopeDepth, Label* jumpTarget);
     
    856848
    857849    private:
    858         void emitCompareFinallyActionAndJumpIf(OpcodeID compareOpcode, int value, Label* jumpTarget);
    859 
    860         int bytecodeOffsetToJumpID(unsigned offset)
    861         {
    862             int jumpID = offset + static_cast<int>(CompletionType::NumberOfTypes);
    863             ASSERT(jumpID >= static_cast<int>(CompletionType::NumberOfTypes));
    864             return jumpID;
    865         }
    866 
    867         bool allocateFinallyRegisters();
    868         void releaseFinallyRegisters();
     850        bool allocateCompletionRecordRegisters();
     851        void releaseCompletionRecordRegisters();
    869852
    870853    public:
     
    11011084        RegisterID* m_promiseCapabilityRegister { nullptr };
    11021085
    1103         // The spec at https://tc39.github.io/ecma262/#sec-completion-record-specification-type says
    1104         // that there are 5 types of completions. Conceptually, we'll set m_finallyActionRegister
    1105         // to one of these completion types. However, to optimize our implementation, we'll encode
    1106         // these type info as follows:
    1107         //
    1108         //     CompletionType::Normal   - m_finallyActionRegister is empty.
    1109         //     CompletionType::Break    - m_finallyActionRegister is an int JSValue jumpID.
    1110         //     CompletionType::Continue - m_finallyActionRegister is an int JSValue jumpID.
    1111         //     CompletionType::Return   - m_finallyActionRegister is the Return enum as an int JSValue.
    1112         //     CompletionType::Throw    - m_finallyActionRegister is the Exception object to rethrow.
    1113         //
    1114         // Hence, of the 5 completion types, only the CompletionType::Return enum value is used in
    1115         // our implementation. The rest are just provided for completeness.
    1116 
    1117         enum class CompletionType : int {
    1118             Normal,
    1119             Break,
    1120             Continue,
    1121             Return,
    1122             Throw,
    1123 
    1124             NumberOfTypes
    1125         };
    1126 
    1127         RefPtr<RegisterID> m_finallyActionRegister;
    1128         RefPtr<RegisterID> m_finallyReturnValueRegister;
     1086        RefPtr<RegisterID> m_completionTypeRegister;
     1087        RefPtr<RegisterID> m_completionValueRegister;
    11291088
    11301089        FinallyContext* m_currentFinallyContext { nullptr };
     
    11441103        void popLocalControlFlowScope();
    11451104
    1146         // FIXME: Restore overflow checking with UnsafeVectorOverflow once SegmentVector supports it. 
     1105        // FIXME: Restore overflow checking with UnsafeVectorOverflow once SegmentVector supports it.
    11471106        // https://bugs.webkit.org/show_bug.cgi?id=165980
    11481107        SegmentedVector<ControlFlowScope, 16> m_controlFlowScopeStack;
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r209952 r209974  
    32883288
    32893289    ASSERT(m_catchBlock || m_finallyBlock);
    3290     BytecodeGenerator::FinallyRegistersScope finallyRegistersScope(generator, m_finallyBlock);
     3290    BytecodeGenerator::CompletionRecordScope completionRecordScope(generator, m_finallyBlock);
    32913291
    32923292    RefPtr<Label> catchLabel;
     
    33173317    generator.emitNode(dst, m_tryBlock);
    33183318
    3319     // The finallyActionRegister is an empty value by default, which implies CompletionType::Normal.
    33203319    if (m_finallyBlock)
    33213320        generator.emitJump(finallyLabel.get());
     
    33523351
    33533352        if (m_finallyBlock) {
    3354             generator.emitSetFinallyActionToNormalCompletion();
     3353            generator.emitSetCompletionType(CompletionType::Normal);
    33553354            generator.emitJump(finallyLabel.get());
    33563355            generator.popTry(tryData, finallyViaThrowLabel.get());
     
    33673366        generator.emitLabel(finallyViaThrowLabel.get());
    33683367        RegisterID* unused = generator.newTemporary();
    3369         generator.emitCatch(generator.finallyActionRegister(), unused);
    3370         // Setting the finallyActionRegister to the caught exception here implies CompletionType::Throw.
     3368        generator.emitCatch(generator.completionValueRegister(), unused);
     3369        generator.emitSetCompletionType(CompletionType::Throw);
    33713370
    33723371        // Entry to the finally block for CompletionTypes other than Throw.
Note: See TracChangeset for help on using the changeset viewer.