| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog +63 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2013-04-04  Filip Pizlo  <fpizlo@apple.com>
2
3
        FTL should have OSR exit
4
        https://bugs.webkit.org/show_bug.cgi?id=113623
5
6
        Reviewed by NOBODY (OOPS!).
7
        
8
        Work in progress.
9
10
        * dfg/DFGOSRExit.cpp:
11
        (JSC::DFG::OSRExit::OSRExit):
12
        (DFG):
13
        * dfg/DFGOSRExit.h:
14
        (OSRExit):
15
        * dfg/DFGOSRExitBase.cpp: Added.
16
        (DFG):
17
        (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
18
        * dfg/DFGOSRExitBase.h: Added.
19
        (DFG):
20
        (JSC::DFG::OSRExitBase::OSRExitBase):
21
        (OSRExitBase):
22
        (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
23
        * ftl/FTLExitArgument.cpp: Added.
24
        (FTL):
25
        (JSC::FTL::ExitArgument::dump):
26
        * ftl/FTLExitArgument.h: Added.
27
        (FTL):
28
        (ExitArgumentRepresentation):
29
        (ExitArgument):
30
        (JSC::FTL::ExitArgument::ExitArgument):
31
        (JSC::FTL::ExitArgument::operator!):
32
        (JSC::FTL::ExitArgument::format):
33
        (JSC::FTL::ExitArgument::argument):
34
        (JSC::FTL::ExitArgument::representation):
35
        * ftl/FTLExitValue.cpp: Added.
36
        (FTL):
37
        (JSC::FTL::ExitValue::dump):
38
        * ftl/FTLExitValue.h: Added.
39
        (FTL):
40
        (ExitValue):
41
        (JSC::FTL::ExitValue::ExitValue):
42
        (JSC::FTL::ExitValue::operator!):
43
        (JSC::FTL::ExitValue::dead):
44
        (JSC::FTL::ExitValue::inJSStack):
45
        (JSC::FTL::ExitValue::constant):
46
        (JSC::FTL::ExitValue::argument):
47
        (JSC::FTL::ExitValue::kind):
48
        (JSC::FTL::ExitValue::isDead):
49
        (JSC::FTL::ExitValue::isInJSStack):
50
        (JSC::FTL::ExitValue::isConstant):
51
        (JSC::FTL::ExitValue::isArgument):
52
        * ftl/FTLFormattedValue.h:
53
        (FTL):
54
        * ftl/FTLOSRExit.h: Added.
55
        (FTL):
56
        (OSRExit):
57
        * ftl/FTLValueFormat.cpp: Added.
58
        (WTF):
59
        (WTF::printInternal):
60
        * ftl/FTLValueFormat.h: Added.
61
        (FTL):
62
        (WTF):
63
1
2013-04-03  Filip Pizlo  <fpizlo@apple.com>
64
2013-04-03  Filip Pizlo  <fpizlo@apple.com>
2
65
3
        fourthTier: put DFG data into a DFG::JITCode, and put common DFG and FTL data into something accessible from both DFG::JITCode and FTL::JITCode
66
        fourthTier: put DFG data into a DFG::JITCode, and put common DFG and FTL data into something accessible from both DFG::JITCode and FTL::JITCode
- Source/JavaScriptCore/dfg/DFGAbstractState.cpp -1 / +2 lines
Lines 95-101 void AbstractState::initialize(Graph& gr Source/JavaScriptCore/dfg/DFGAbstractState.cpp_sec1
95
            continue;
95
            continue;
96
        }
96
        }
97
        
97
        
98
        SpeculatedType prediction = node->variableAccessData()->prediction();
98
        SpeculatedType prediction =
99
            node->variableAccessData()->argumentAwarePrediction();
99
        if (isInt32Speculation(prediction))
100
        if (isInt32Speculation(prediction))
100
            root->valuesAtHead.argument(i).set(SpecInt32);
101
            root->valuesAtHead.argument(i).set(SpecInt32);
101
        else if (isBooleanSpeculation(prediction))
102
        else if (isBooleanSpeculation(prediction))
- Source/JavaScriptCore/dfg/DFGMinifiedNode.h +1 lines
Lines 51-56 inline bool belongsInMinifiedGraph(NodeT Source/JavaScriptCore/dfg/DFGMinifiedNode.h_sec1
51
    case PhantomArguments:
51
    case PhantomArguments:
52
        return true;
52
        return true;
53
    default:
53
    default:
54
        ASSERT(!needsOSRBackwardRewiring(type) && !needsOSRForwardRewiring(type));
54
        return false;
55
        return false;
55
    }
56
    }
56
}
57
}
- Source/JavaScriptCore/dfg/DFGNodeType.h +19 lines
Lines 287-292 inline NodeFlags defaultFlags(NodeType o Source/JavaScriptCore/dfg/DFGNodeType.h_sec1
287
    }
287
    }
288
}
288
}
289
289
290
inline bool needsOSRBackwardRewiring(NodeType op)
291
{
292
    return op == UInt32ToNumber;
293
}
294
295
inline bool needsOSRForwardRewiring(NodeType op)
296
{
297
    switch (op) {
298
    case Int32ToDouble:
299
    case ForwardInt32ToDouble:
300
    case ValueToInt32:
301
    case UInt32ToNumber:
302
    case DoubleAsInt32:
303
        return true;
304
    default:
305
        return false;
306
    }
307
}
308
290
} } // namespace JSC::DFG
309
} } // namespace JSC::DFG
291
310
292
#endif // ENABLE(DFG_JIT)
311
#endif // ENABLE(DFG_JIT)
- Source/JavaScriptCore/dfg/DFGOSRExit.cpp -52 / +7 lines
Lines 36-50 Source/JavaScriptCore/dfg/DFGOSRExit.cpp_sec1
36
namespace JSC { namespace DFG {
36
namespace JSC { namespace DFG {
37
37
38
OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAValueProfile valueProfile, SpeculativeJIT* jit, unsigned streamIndex, unsigned recoveryIndex)
38
OSRExit::OSRExit(ExitKind kind, JSValueSource jsValueSource, MethodOfGettingAValueProfile valueProfile, SpeculativeJIT* jit, unsigned streamIndex, unsigned recoveryIndex)
39
    : m_jsValueSource(jsValueSource)
39
    : OSRExitBase(kind, jit->m_codeOriginForOSR)
40
    , m_jsValueSource(jsValueSource)
40
    , m_valueProfile(valueProfile)
41
    , m_valueProfile(valueProfile)
41
    , m_patchableCodeOffset(0)
42
    , m_patchableCodeOffset(0)
42
    , m_codeOrigin(jit->m_codeOriginForOSR)
43
    , m_codeOrigin(jit->m_codeOriginForOSR)
43
    , m_codeOriginForExitProfile(m_codeOrigin)
44
    , m_recoveryIndex(recoveryIndex)
44
    , m_recoveryIndex(recoveryIndex)
45
    , m_watchpointIndex(std::numeric_limits<unsigned>::max())
45
    , m_watchpointIndex(std::numeric_limits<unsigned>::max())
46
    , m_kind(kind)
47
    , m_count(0)
48
    , m_streamIndex(streamIndex)
46
    , m_streamIndex(streamIndex)
49
    , m_lastSetOperand(jit->m_lastSetOperand)
47
    , m_lastSetOperand(jit->m_lastSetOperand)
50
{
48
{
Lines 73-129 void OSRExit::correctJump(LinkBuffer& li Source/JavaScriptCore/dfg/DFGOSRExit.cpp_sec2
73
    m_patchableCodeOffset = linkBuffer.offsetOf(label);
71
    m_patchableCodeOffset = linkBuffer.offsetOf(label);
74
}
72
}
75
73
76
bool OSRExit::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
77
{
78
    if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
79
        return false;
80
    
81
    FrequentExitSite exitSite;
82
    
83
    if (m_kind == ArgumentsEscaped) {
84
        // Count this one globally. It doesn't matter where in the code block the arguments excaped;
85
        // the fact that they did is not associated with any particular instruction.
86
        exitSite = FrequentExitSite(m_kind);
87
    } else
88
        exitSite = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind);
89
    
90
    return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOriginForExitProfile, profiledCodeBlock)->addFrequentExitSite(exitSite);
91
}
92
93
void OSRExit::convertToForward(BasicBlock* block, Node* currentNode, unsigned nodeIndex, const ValueRecovery& valueRecovery)
74
void OSRExit::convertToForward(BasicBlock* block, Node* currentNode, unsigned nodeIndex, const ValueRecovery& valueRecovery)
94
{
75
{
95
    // Check that either the current node is a SetLocal, or the preceding node was a
76
    Node* node;
96
    // SetLocal with the same code origin, or that we've provided a valueRecovery.
77
    Node* lastMovHint;
97
    if (!ASSERT_DISABLED
78
    doSearchForForwardConversion(block, currentNode, nodeIndex, !!valueRecovery);
98
        && !valueRecovery
79
99
        && !currentNode->containsMovHint()) {
100
        Node* setLocal = block->at(nodeIndex - 1);
101
        ASSERT_UNUSED(setLocal, setLocal->containsMovHint());
102
        ASSERT_UNUSED(setLocal, setLocal->codeOrigin == currentNode->codeOrigin);
103
    }
104
    
105
    // Find the first node for the next bytecode instruction. Also track the last mov hint
106
    // on this node.
107
    unsigned indexInBlock = nodeIndex + 1;
108
    Node* node = 0;
109
    Node* lastMovHint = 0;
110
    for (;;) {
111
        if (indexInBlock == block->size()) {
112
            // This is an inline return. Give up and do a backwards speculation. This is safe
113
            // because an inline return has its own bytecode index and it's always safe to
114
            // reexecute that bytecode.
115
            ASSERT(node->op() == Jump);
116
            return;
117
        }
118
        node = block->at(indexInBlock);
119
        if (node->containsMovHint() && node->child1() == currentNode)
120
            lastMovHint = node;
121
        if (node->codeOrigin != currentNode->codeOrigin)
122
            break;
123
        indexInBlock++;
124
    }
125
    
126
    ASSERT(node->codeOrigin != currentNode->codeOrigin);
80
    ASSERT(node->codeOrigin != currentNode->codeOrigin);
81
    
127
    m_codeOrigin = node->codeOrigin;
82
    m_codeOrigin = node->codeOrigin;
128
    
83
    
129
    if (!valueRecovery)
84
    if (!valueRecovery)
- Source/JavaScriptCore/dfg/DFGOSRExit.h -16 / +3 lines
Lines 1-5 Source/JavaScriptCore/dfg/DFGOSRExit.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2011 Apple Inc. All rights reserved.
2
 * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 34-39 Source/JavaScriptCore/dfg/DFGOSRExit.h_sec2
34
#include "DFGCommon.h"
34
#include "DFGCommon.h"
35
#include "DFGExitProfile.h"
35
#include "DFGExitProfile.h"
36
#include "DFGGPRInfo.h"
36
#include "DFGGPRInfo.h"
37
#include "DFGOSRExitBase.h"
37
#include "DFGValueRecoveryOverride.h"
38
#include "DFGValueRecoveryOverride.h"
38
#include "MacroAssembler.h"
39
#include "MacroAssembler.h"
39
#include "MethodOfGettingAValueProfile.h"
40
#include "MethodOfGettingAValueProfile.h"
Lines 84-90 private: Source/JavaScriptCore/dfg/DFGOSRExit.h_sec3
84
//
85
//
85
// This structure describes how to exit the speculative path by
86
// This structure describes how to exit the speculative path by
86
// going into baseline code.
87
// going into baseline code.
87
struct OSRExit {
88
struct OSRExit : public OSRExitBase {
88
    OSRExit(ExitKind, JSValueSource, MethodOfGettingAValueProfile, SpeculativeJIT*, unsigned streamIndex, unsigned recoveryIndex = UINT_MAX);
89
    OSRExit(ExitKind, JSValueSource, MethodOfGettingAValueProfile, SpeculativeJIT*, unsigned streamIndex, unsigned recoveryIndex = UINT_MAX);
89
    
90
    
90
    MacroAssemblerCodeRef m_code;
91
    MacroAssemblerCodeRef m_code;
Lines 94-114 struct OSRExit { Source/JavaScriptCore/dfg/DFGOSRExit.h_sec4
94
95
95
    unsigned m_patchableCodeOffset;
96
    unsigned m_patchableCodeOffset;
96
    CodeOrigin m_codeOrigin;
97
    CodeOrigin m_codeOrigin;
97
    CodeOrigin m_codeOriginForExitProfile;
98
    
98
    
99
    unsigned m_recoveryIndex;
99
    unsigned m_recoveryIndex;
100
    unsigned m_watchpointIndex;
100
    unsigned m_watchpointIndex;
101
    
101
    
102
    ExitKind m_kind;
103
    uint32_t m_count;
104
    
105
    bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
106
    {
107
        if (!m_count || !exitKindIsCountable(m_kind))
108
            return false;
109
        return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
110
    }
111
112
    void setPatchableCodeOffset(MacroAssembler::PatchableJump);
102
    void setPatchableCodeOffset(MacroAssembler::PatchableJump);
113
    MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
103
    MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
114
    CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
104
    CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
Lines 120-128 struct OSRExit { Source/JavaScriptCore/dfg/DFGOSRExit.h_sec5
120
    int m_lastSetOperand;
110
    int m_lastSetOperand;
121
    
111
    
122
    RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride;
112
    RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride;
123
124
private:
125
    bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
126
};
113
};
127
114
128
struct SpeculationFailureDebugInfo {
115
struct SpeculationFailureDebugInfo {
- Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp +92 lines
Line 0 Source/JavaScriptCore/dfg/DFGOSRExitBase.cpp_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "DFGOSRExitBase.h"
28
29
#if ENABLE(DFG_JIT)
30
31
namespace JSC { namespace DFG {
32
33
bool OSRExitBase::considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
34
{
35
    if (static_cast<double>(m_count) / dfgCodeBlock->osrExitCounter() <= Options::osrExitProminenceForFrequentExitSite())
36
        return false;
37
    
38
    FrequentExitSite exitSite;
39
    
40
    if (m_kind == ArgumentsEscaped) {
41
        // Count this one globally. It doesn't matter where in the code block the arguments excaped;
42
        // the fact that they did is not associated with any particular instruction.
43
        exitSite = FrequentExitSite(m_kind);
44
    } else
45
        exitSite = FrequentExitSite(m_codeOriginForExitProfile.bytecodeIndex, m_kind);
46
    
47
    return baselineCodeBlockForOriginAndBaselineCodeBlock(m_codeOriginForExitProfile, profiledCodeBlock)->addFrequentExitSite(exitSite);
48
}
49
50
bool OSRExitBase::doSearchForForwardConversion(
51
    BasicBlock* block, Node* currentNode, unsigned nodeIndex, bool hasValueRecovery,
52
    Node*& node, Node*& lastMovHint)
53
{
54
    // Check that either the current node is a SetLocal, or the preceding node was a
55
    // SetLocal with the same code origin, or that we've provided a valueRecovery.
56
    if (!ASSERT_DISABLED
57
        && !hasValueRecovery
58
        && !currentNode->containsMovHint()) {
59
        Node* setLocal = block->at(nodeIndex - 1);
60
        ASSERT_UNUSED(setLocal, setLocal->containsMovHint());
61
        ASSERT_UNUSED(setLocal, setLocal->codeOrigin == currentNode->codeOrigin);
62
    }
63
    
64
    // Find the first node for the next bytecode instruction. Also track the last mov hint
65
    // on this node.
66
    unsigned indexInBlock = nodeIndex + 1;
67
    node = 0;
68
    lastMovHint = 0;
69
    for (;;) {
70
        if (indexInBlock == block->size()) {
71
            // This is an inline return. Give up and do a backwards speculation. This is safe
72
            // because an inline return has its own bytecode index and it's always safe to
73
            // reexecute that bytecode.
74
            ASSERT(node->op() == Jump);
75
            return false;
76
        }
77
        node = block->at(indexInBlock);
78
        if (node->containsMovHint() && node->child1() == currentNode)
79
            lastMovHint = node;
80
        if (node->codeOrigin != currentNode->codeOrigin)
81
            break;
82
        indexInBlock++;
83
    }
84
    
85
    ASSERT(node->codeOrigin != currentNode->codeOrigin);
86
    return true;
87
}
88
89
} } // namespace JSC::DFG
90
91
#endif // ENABLE(DFG_JIT)
92
- Source/JavaScriptCore/dfg/DFGOSRExitBase.h +75 lines
Line 0 Source/JavaScriptCore/dfg/DFGOSRExitBase.h_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef DFGOSRExitBase_h
27
#define DFGOSRExitBase_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(DFG_JIT)
32
33
#include "CodeOrigin.h"
34
#include "DFGExitProfile.h"
35
36
namespace JSC { namespace DFG {
37
38
// Provides for the OSR exit profiling functionality that is common between the DFG
39
// and the FTL.
40
41
struct OSRExitBase {
42
    OSRExitBase(ExitKind kind, CodeOrigin origin)
43
        : m_kind(kind)
44
        , m_count(0)
45
        , m_codeOriginForExitProfile(origin)
46
    {
47
    }
48
    
49
    ExitKind m_kind;
50
    uint32_t m_count;
51
    
52
    CodeOrigin m_codeOriginForExitProfile;
53
54
    bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
55
    {
56
        if (!m_count || !exitKindIsCountable(m_kind))
57
            return false;
58
        return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
59
    }
60
    
61
    // Returns true if the forward conversion is really needed.
62
    bool doSearchForForwardConversion(
63
        BasicBlock*, Node* currentNode, unsigned nodeIndex, bool hasValueRecovery,
64
        Node*& nextBCNode, Node*& lastMovHint);
65
66
private:
67
    bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
68
};
69
70
} } // namespace JSC::DFG
71
72
#endif // ENABLE(DFG_JIT)
73
74
#endif // DFGOSRExitBase_h
75
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp -1 / +1 lines
Lines 1777-1783 void SpeculativeJIT::checkArgumentTypes( Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp_sec1
1777
            continue;
1777
            continue;
1778
        
1778
        
1779
        VirtualRegister virtualRegister = variableAccessData->local();
1779
        VirtualRegister virtualRegister = variableAccessData->local();
1780
        SpeculatedType predictedType = variableAccessData->prediction();
1780
        SpeculatedType predictedType = variableAccessData->argumentAwarePrediction();
1781
1781
1782
        JSValueSource valueSource = JSValueSource(JITCompiler::addressFor(virtualRegister));
1782
        JSValueSource valueSource = JSValueSource(JITCompiler::addressFor(virtualRegister));
1783
        
1783
        
- Source/JavaScriptCore/dfg/DFGValueSource.h -1 / +1 lines
Lines 131-137 public: Source/JavaScriptCore/dfg/DFGValueSource.h_sec1
131
    {
131
    {
132
        if (isInt32Speculation(prediction))
132
        if (isInt32Speculation(prediction))
133
            return ValueSource(Int32InJSStack);
133
            return ValueSource(Int32InJSStack);
134
        if (isArraySpeculation(prediction) || isCellSpeculation(prediction))
134
        if (isCellSpeculation(prediction))
135
            return ValueSource(CellInJSStack);
135
            return ValueSource(CellInJSStack);
136
        if (isBooleanSpeculation(prediction))
136
        if (isBooleanSpeculation(prediction))
137
            return ValueSource(BooleanInJSStack);
137
            return ValueSource(BooleanInJSStack);
- Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp -1 / +2 lines
Lines 214-220 void VariableEventStream::reconstruct( Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp_sec1
214
            
214
            
215
            bool found = false;
215
            bool found = false;
216
            
216
            
217
            if (node && node->op() == UInt32ToNumber) {
217
            if (node && needsOSRBackwardRewiring(node->op())) {
218
                MinifiedID id = node->child1();
218
                MinifiedID id = node->child1();
219
                if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, graph.at(id)))
219
                if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, graph.at(id)))
220
                    continue;
220
                    continue;
Lines 257-262 void VariableEventStream::reconstruct( Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp_sec2
257
                        doubleAsInt32ID = id;
257
                        doubleAsInt32ID = id;
258
                        break;
258
                        break;
259
                    default:
259
                    default:
260
                        ASSERT(!needsOSRForwardRewiring(node->op()));
260
                        break;
261
                        break;
261
                    }
262
                    }
262
                }
263
                }
- Source/JavaScriptCore/ftl/FTLExitArgument.cpp +41 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitArgument.cpp_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "FTLExitArgument.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
void ExitArgument::dump(PrintStream& out) const
34
{
35
    out.print("arg", argument(), " as ", format());
36
}
37
38
} } // namespace JSC::FTL
39
40
#endif // ENABLE(FTL_JIT)
41
- Source/JavaScriptCore/ftl/FTLExitArgument.h +93 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitArgument.h_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef FTLExitArgument_h
27
#define FTLExitArgument_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLValueFormat.h"
34
#include <wtf/PrintStream.h>
35
36
namespace JSC { namespace FTL {
37
38
struct ExitArgumentRepresentation {
39
    ValueFormat format;
40
    unsigned argument;
41
};
42
43
class ExitArgument {
44
public:
45
    ExitArgument()
46
    {
47
        m_representation.format = InvalidValueFormat;
48
    }
49
    
50
    ExitArgument(ValueFormat format, unsigned argument)
51
    {
52
        m_representation.format = format;
53
        m_representation.argument = argument;
54
    }
55
    
56
    explicit ExitArgument(ExitArgumentRepresentation representation)
57
    {
58
        m_representation = representation;
59
    }
60
    
61
    bool operator!() const { return m_representation.format == InvalidValueFormat; }
62
    
63
    ValueFormat format() const
64
    {
65
        ASSERT(*this);
66
        return m_representation.format;
67
    }
68
    
69
    unsigned argument() const
70
    {
71
        ASSERT(*this);
72
        return m_representation.argument;
73
    }
74
    
75
    ExitArgument withFormat(ValueFormat format)
76
    {
77
        return ExitArgument(format, argument());
78
    }
79
    
80
    ExitArgumentRepresentation representation() const { return m_representation; }
81
    
82
    void dump(PrintStream&) const;
83
    
84
private:
85
    ExitArgumentRepresentation m_representation;
86
};
87
88
} } // namespace JSC::FTL
89
90
#endif // ENABLE(FTL_JIT)
91
92
#endif // FTLExitArgument_h
93
- Source/JavaScriptCore/ftl/FTLExitValue.cpp +59 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitValue.cpp_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "FTLExitValue.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
void ExitValue::dump(PrintStream& out) const
34
{
35
    switch (kind()) {
36
    case InvalidExitValue:
37
        out.print("Invalid");
38
        return;
39
    case ExitValueDead:
40
        out.print("Dead");
41
        return;
42
    case ExitValueArgument:
43
        out.print("Argument(", exitArgument(), ")");
44
        return;
45
    case ExitValueConstant:
46
        out.print("Constant(", constant(), ")");
47
        return;
48
    case ExitValueInJSStack:
49
        out.print("InJSStack");
50
        return;
51
    }
52
    
53
    RELEASE_ASSERT_NOT_REACHED();
54
}
55
56
} } // namespace JSC::FTL
57
58
#endif // ENABLE(FTL_JIT)
59
- Source/JavaScriptCore/ftl/FTLExitValue.h +160 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitValue.h_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef FTLExitValue_h
27
#define FTLExitValue_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLExitArgument.h"
34
#include "JSCJSValue.h"
35
#include <wtf/PrintStream.h>
36
37
namespace JSC { namespace FTL {
38
39
// This is like ValueRecovery, but respects the way that the FTL does OSR
40
// exit: the live non-constant non-flushed values are passed as arguments
41
// to a noreturn tail call. ExitValue is hence mostly responsible for
42
// telling us the mapping between operands in bytecode and the arguments to
43
// the call.
44
45
enum ExitValueKind {
46
    InvalidExitValue,
47
    ExitValueDead,
48
    ExitValueArgument,
49
    ExitValueConstant
50
    ExitValueInJSStack,
51
    ExitValueInJSStackAsInt32,
52
    ExitValueInJSStackAsBoolean,
53
    ExitValueInJSStackAsDouble
54
};
55
56
class ExitValue {
57
public:
58
    ExitValue()
59
        : m_kind(InvalidExitValue)
60
    {
61
    }
62
    
63
    bool operator!() const { return m_kind == InvalidExitValue; }
64
    
65
    static ExitValue dead()
66
    {
67
        ExitValue result;
68
        result.m_kind = ExitValueDead;
69
        return result;
70
    }
71
    
72
    static ExitValue inJSStack()
73
    {
74
        ExitValue result;
75
        result.m_kind = ExitValueInJSStack;
76
        return result;
77
    }
78
    
79
    static ExitValue inJSStackAsInt32()
80
    {
81
        ExitValue result;
82
        result.m_kind = ExitValueInJSStackAsInt32;
83
        return result;
84
    }
85
    
86
    static ExitValue inJSStackAsBoolean()
87
    {
88
        ExitValue result;
89
        result.m_kind = ExitValueInJSStackAsBoolean;
90
        return result;
91
    }
92
    
93
    static ExitValue inJSStackAsDouble()
94
    {
95
        ExitValue result;
96
        result.m_kind = ExitValueInJSStackAsDouble;
97
        return result;
98
    }
99
    
100
    static ExitValue constant(JSValue value)
101
    {
102
        ExitValue result;
103
        result.m_kind = ExitValueConstant;
104
        result.u.constant = JSValue::encode(value);
105
        return result;
106
    }
107
    
108
    static ExitValue exitArgument(const ExitArgument& argument)
109
    {
110
        ExitValue result;
111
        result.m_kind = ExitValueArgument;
112
        result.u.argument = argument.representation();
113
        return result;
114
    }
115
    
116
    ExitValueKind kind() const { return m_kind; }
117
    
118
    bool isDead() const { return kind() == ExitValueDead; }
119
    bool isInJSStackSomehow() const
120
    {
121
        switch (kind()) {
122
        case ExitValueInJSStack:
123
        case ExitValueInJSStackAsInt32:
124
        case ExitValueInJSStackAsBoolean:
125
        case ExitValueInJSStackAsDouble:
126
            return true;
127
        default:
128
            return false;
129
        }
130
    }
131
    bool isConstant() const { return kind() == ExitValueConstant; }
132
    bool isArgument() const { return kind() == ExitValueArgument; }
133
    
134
    ExitArgument exitArgument() const
135
    {
136
        ASSERT(isArgument());
137
        return ExitArgument(u.argument);
138
    }
139
    
140
    JSValue constant() const
141
    {
142
        ASSERT(isConstant());
143
        return JSValue::decode(u.constant);
144
    }
145
    
146
    void dump(PrintStream&) const;
147
    
148
private:
149
    ExitValueKind m_kind;
150
    union {
151
        ExitArgumentRepresentation argument;
152
        EncodedJSValue constant;
153
    } u;
154
};
155
156
} } // namespace JSC::FTL
157
158
#endif // ENABLE(FTL_JIT)
159
160
#endif // FTLExitValue_h
- Source/JavaScriptCore/ftl/FTLFormattedValue.h -12 / +1 lines
Lines 31-36 Source/JavaScriptCore/ftl/FTLFormattedValue.h_sec1
31
#if ENABLE(FTL_JIT)
31
#if ENABLE(FTL_JIT)
32
32
33
#include "FTLAbbreviations.h"
33
#include "FTLAbbreviations.h"
34
#include "FTLValueFormat.h"
34
35
35
namespace JSC { namespace FTL {
36
namespace JSC { namespace FTL {
36
37
Lines 41-58 namespace JSC { namespace FTL { Source/JavaScriptCore/ftl/FTLFormattedValue.h_sec2
41
// use this in situations where there is no good way to say what node the value came
42
// use this in situations where there is no good way to say what node the value came
42
// from.
43
// from.
43
44
44
// Note that this is awkwardly similar to DataFormat in other parts of JSC, except that
45
// unlike DataFormat and like ValueRecovery, it distinguishes between UInt32 and Int32.
46
47
enum ValueFormat {
48
    InvalidValueFormat,
49
    ValueFormatInt32,
50
    ValueFormatUInt32,
51
    ValueFormatBoolean,
52
    ValueFormatJSValue,
53
    ValueFormatDouble
54
};
55
56
class FormattedValue {
45
class FormattedValue {
57
public:
46
public:
58
    FormattedValue()
47
    FormattedValue()
- Source/JavaScriptCore/ftl/FTLJITCode.cpp +10 lines
Lines 42-47 JITCode::~JITCode() Source/JavaScriptCore/ftl/FTLJITCode.cpp_sec1
42
        LLVMDisposeExecutionEngine(m_engine);
42
        LLVMDisposeExecutionEngine(m_engine);
43
}
43
}
44
44
45
void JITCode::initializeExitThunks(CodeRef exitThunks)
46
{
47
    m_exitThunks = exitThunks;
48
}
49
45
void JITCode::initializeCode(LLVMExecutionEngineRef engine, CodeRef entrypoint)
50
void JITCode::initializeCode(LLVMExecutionEngineRef engine, CodeRef entrypoint)
46
{
51
{
47
    m_engine = engine;
52
    m_engine = engine;
Lines 97-102 bool JITCode::contains(void*) Source/JavaScriptCore/ftl/FTLJITCode.cpp_sec2
97
    return false;
102
    return false;
98
}
103
}
99
104
105
CodePtr JITCode::exitThunks()
106
{
107
    return m_exitThunks.code();
108
}
109
100
JITCode* JITCode::ftl()
110
JITCode* JITCode::ftl()
101
{
111
{
102
    return this;
112
    return this;
- Source/JavaScriptCore/ftl/FTLJITCode.h +5 lines
Lines 48-59 public: Source/JavaScriptCore/ftl/FTLJITCode.h_sec1
48
    size_t size();
48
    size_t size();
49
    bool contains(void*);
49
    bool contains(void*);
50
    
50
    
51
    void initializeExitThunks(CodeRef);
51
    void initializeCode(LLVMExecutionEngineRef, CodeRef entrypoint);
52
    void initializeCode(LLVMExecutionEngineRef, CodeRef entrypoint);
52
    
53
    
54
    CodePtr exitThunks();
55
    
53
    JITCode* ftl();
56
    JITCode* ftl();
54
    DFG::CommonData* dfgCommon();
57
    DFG::CommonData* dfgCommon();
55
    
58
    
56
    DFG::CommonData common;
59
    DFG::CommonData common;
60
    SegmentedVector<OSRExit, 8> osrExit;
57
    
61
    
58
private:
62
private:
59
    // FIXME: LLVM should use our own JIT memory allocator, and we shouldn't have to
63
    // FIXME: LLVM should use our own JIT memory allocator, and we shouldn't have to
Lines 61-66 private: Source/JavaScriptCore/ftl/FTLJITCode.h_sec2
61
    // https://bugs.webkit.org/show_bug.cgi?id=113619
65
    // https://bugs.webkit.org/show_bug.cgi?id=113619
62
    LLVMExecutionEngineRef m_engine;
66
    LLVMExecutionEngineRef m_engine;
63
    CodeRef m_entrypoint;
67
    CodeRef m_entrypoint;
68
    CodeRef m_exitThunks;
64
};
69
};
65
70
66
} } // namespace JSC::FTL
71
} } // namespace JSC::FTL
- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp -19 / +132 lines
Lines 57-62 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec1
57
        , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
57
        , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
58
        , m_locals32(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
58
        , m_locals32(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
59
        , m_locals64(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
59
        , m_locals64(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
60
        , m_valueSources(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
60
        , m_state(state.graph)
61
        , m_state(state.graph)
61
    {
62
    {
62
    }
63
    }
Lines 151-158 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec2
151
    
152
    
152
    void transferAndCheckArguments()
153
    void transferAndCheckArguments()
153
    {
154
    {
154
        // FIXME: Set up the OSR story here.
155
        // While checking arguments, everything is in the stack.
155
        // https://bugs.webkit.org/show_bug.cgi?id=113623
156
        for (unsigned i = size(); i--;)
157
            m_valueSources[i] = ValueSource(ValueInJSStack);
156
        
158
        
157
        for (int i = 0; i < m_graph.m_codeBlock->numParameters(); ++i) {
159
        for (int i = 0; i < m_graph.m_codeBlock->numParameters(); ++i) {
158
            Node* node = m_graph.m_arguments[i];
160
            Node* node = m_graph.m_arguments[i];
Lines 170-176 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec3
170
            if (variable->shouldUnboxIfPossible()) {
172
            if (variable->shouldUnboxIfPossible()) {
171
                RELEASE_ASSERT(!variable->shouldUseDoubleFormat());
173
                RELEASE_ASSERT(!variable->shouldUseDoubleFormat());
172
                
174
                
173
                SpeculatedType prediction = variable->prediction();
175
                SpeculatedType prediction = variable->argumentAwarePrediction();
174
                
176
                
175
                if (isInt32Speculation(prediction)) {
177
                if (isInt32Speculation(prediction)) {
176
                    speculateBackward(BadType, jsValue, node, isNotInt32(jsValue));
178
                    speculateBackward(BadType, jsValue, node, isNotInt32(jsValue));
Lines 216-228 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec4
216
        // make IR dumps easier to read.
218
        // make IR dumps easier to read.
217
        m_out.appendTo(lowBlock, m_nextLowBlock);
219
        m_out.appendTo(lowBlock, m_nextLowBlock);
218
        
220
        
219
        // FIXME: We should track the OSR situation here.
221
        for (unsigned i = m_valueSources.size(); i--;) {
220
        // https://bugs.webkit.org/show_bug.cgi?id=113623
222
            Node* node = m_highBlock->variablesAtHead[i];
223
            if (!node) {
224
                m_valueSources[i] = ValueSource(SourceIsDead);
225
                continue;
226
            }
227
            
228
            VariableAccessData* variable = node->variableAccessData();
229
            SpeculatedType prediction = variable->argumentAwarePrediction();
230
            
231
            if (variable->isArgumentsAlias()) {
232
                m_valueSources[i] = ValueSource(ArgumentsSource);
233
                continue;
234
            }
235
            
236
            if (!node->shouldGenerate()) {
237
                m_valueSources[i] = ValueSource(SourceIsDead);
238
                continue;
239
            }
240
            
241
            if (m_flushedLocalOps.contains(node)) {
242
                // This value will have been flushed to the JSStack in some form or
243
                // another.
244
                
245
                if (variable->shouldUnboxIfPossible()) {
246
                    if (variable->shouldUseDoubleFormat()) {
247
                        m_valueSources[i] = ValueSource(DoubleInJSStack);
248
                        continue;
249
                    }
250
                    
251
                    if (isInt32Speculation(prediction)) {
252
                        m_valueSources[i] = ValueSource(Int32InJSStack);
253
                        continue;
254
                    }
255
                }
256
                
257
                m_valueSources[i] = ValueSource(ValueInJSStack);
258
                continue;
259
            }
260
            
261
            if (variable->shouldUnboxIfPossible()) {
262
                if (variable->shouldUseDoubleFormat()) {
263
                    m_valueSources[i] = ValueSource(ValueInLocals);
264
                    continue;
265
                }
266
                
267
                if (isInt32Speculation(prediction)) {
268
                    m_valueSources[i] = ValueSource(Int32InLocals);
269
                    continue;
270
                }
271
                
272
                if (isBooleanSpeculation(prediction)) {
273
                    m_valueSources[i] = ValueSource(BooleanInLocals);
274
                    continue;
275
                }
276
            }
277
            
278
            m_valueSources[i] = ValueSource(ValueInLocals);
279
        }
221
        
280
        
222
        m_int32Values.clear();
281
        m_int32Values.clear();
223
        m_jsValueValues.clear();
282
        m_jsValueValues.clear();
224
        m_booleanValues.clear();
283
        m_booleanValues.clear();
225
        m_storageValues.clear();
284
        m_storageValues.clear();
285
        m_timeToLive.clear();
226
        
286
        
227
        m_state.reset();
287
        m_state.reset();
228
        m_state.beginBasicBlock(m_highBlock);
288
        m_state.beginBasicBlock(m_highBlock);
Lines 240-248 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec5
240
        
300
        
241
        bool shouldExecuteEffects = m_state.startExecuting(m_node);
301
        bool shouldExecuteEffects = m_state.startExecuting(m_node);
242
        
302
        
243
        if (!m_node->shouldGenerate())
244
            return; // FIXME: Implement OSR magic here. https://bugs.webkit.org/show_bug.cgi?id=113623
245
        
246
        m_direction = (m_node->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
303
        m_direction = (m_node->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
247
        
304
        
248
        switch (m_node->op()) {
305
        switch (m_node->op()) {
Lines 258-263 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec6
258
        case SetLocal:
315
        case SetLocal:
259
            compileSetLocal();
316
            compileSetLocal();
260
            break;
317
            break;
318
        case MovHint:
319
            compileMovHint();
320
            break;
321
        case ZombieHint:
322
            compileZombieHint();
323
            break;
261
        case MovHintAndCheck:
324
        case MovHintAndCheck:
262
            compileMovHintAndCheck();
325
            compileMovHintAndCheck();
263
            break;
326
            break;
Lines 352-357 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec7
352
            break;
415
            break;
353
        }
416
        }
354
        
417
        
418
        DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, use);
419
        
420
        if (m_node->hasResult())
421
            m_timeToLive.add(m_node, m_node->adjustedRefCount());
422
        
355
        if (shouldExecuteEffects)
423
        if (shouldExecuteEffects)
356
            m_state.executeEffects(nodeIndex);
424
            m_state.executeEffects(nodeIndex);
357
    }
425
    }
Lines 368-375 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec8
368
    
436
    
369
    void compileGetLocal()
437
    void compileGetLocal()
370
    {
438
    {
439
        // GetLocal is one of the few nodes that may be left behind, with !shouldGenerate().
440
        if (!m_node->shouldGenerate())
441
            return;
442
        
371
        VariableAccessData* variable = m_node->variableAccessData();
443
        VariableAccessData* variable = m_node->variableAccessData();
372
        SpeculatedType prediction = variable->prediction();
444
        SpeculatedType prediction = variable->argumentAwarePrediction();
373
        AbstractValue& value = m_state.variables().operand(variable->local());
445
        AbstractValue& value = m_state.variables().operand(variable->local());
374
        
446
        
375
        if (prediction == SpecNone) {
447
        if (prediction == SpecNone) {
Lines 420-432 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec9
420
    
492
    
421
    void compileSetLocal()
493
    void compileSetLocal()
422
    {
494
    {
495
        observeMovHint(m_node);
496
        
423
        VariableAccessData* variable = m_node->variableAccessData();
497
        VariableAccessData* variable = m_node->variableAccessData();
424
        SpeculatedType prediction = variable->prediction();
498
        SpeculatedType prediction = variable->argumentAwarePrediction();
425
        bool needsFlushing = m_flushedLocalOps.contains(m_node);
499
        bool needsFlushing = m_flushedLocalOps.contains(m_node);
426
        
500
        
427
        // FIXME: Handle the MovHint for OSR.
428
        // https://bugs.webkit.org/show_bug.cgi?id=113623
429
        
430
        if (variable->shouldUnboxIfPossible()) {
501
        if (variable->shouldUnboxIfPossible()) {
431
            if (variable->shouldUseDoubleFormat()) {
502
            if (variable->shouldUseDoubleFormat()) {
432
                // FIXME: implement doubles in FTL.
503
                // FIXME: implement doubles in FTL.
Lines 438-458 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec10
438
            if (isInt32Speculation(prediction)) {
509
            if (isInt32Speculation(prediction)) {
439
                LValue value = lowInt32(m_node->child1());
510
                LValue value = lowInt32(m_node->child1());
440
                m_out.set(value, m_locals32.operand(variable->local()));
511
                m_out.set(value, m_locals32.operand(variable->local()));
441
                if (needsFlushing)
512
                if (needsFlushing) {
442
                    m_out.store32(value, payloadFor(variable->local()));
513
                    m_out.store32(value, payloadFor(variable->local()));
514
                    m_valueSources[variable->local()] = ValueSource(Int32InJSStack);
515
                }
443
                return;
516
                return;
444
            }
517
            }
445
            if (isCellSpeculation(prediction)) {
518
            if (isCellSpeculation(prediction)) {
446
                LValue value = lowCell(m_node->child1());
519
                LValue value = lowCell(m_node->child1());
447
                m_out.set(value, m_locals64.operand(variable->local()));
520
                m_out.set(value, m_locals64.operand(variable->local()));
448
                if (needsFlushing)
521
                if (needsFlushing) {
449
                    m_out.store64(value, addressFor(variable->local()));
522
                    m_out.store64(value, addressFor(variable->local()));
523
                    m_valueSources[variable->local()] = ValueSource(CellInJSStack);
524
                }
450
                return;
525
                return;
451
            }
526
            }
452
            if (isBooleanSpeculation(prediction)) {
527
            if (isBooleanSpeculation(prediction)) {
453
                m_out.set(lowBoolean(m_node->child1()), m_localsBoolean.operand(variable->local()));
528
                m_out.set(lowBoolean(m_node->child1()), m_localsBoolean.operand(variable->local()));
454
                if (needsFlushing)
529
                if (needsFlushing) {
455
                    m_out.store64(lowJSValue(m_node->child1()), addressFor(variable->local()));
530
                    m_out.store64(lowJSValue(m_node->child1()), addressFor(variable->local()));
531
                    m_valueSources[variable->local()] = ValueSource(ValueInJSStack);
532
                }
456
                return;
533
                return;
457
            }
534
            }
458
        }
535
        }
Lines 460-477 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec11
460
        LValue value = lowJSValue(m_node->child1());
537
        LValue value = lowJSValue(m_node->child1());
461
        if (variable->isCaptured()) {
538
        if (variable->isCaptured()) {
462
            m_out.store64(value, addressFor(variable->local()));
539
            m_out.store64(value, addressFor(variable->local()));
540
            m_valueSources[variable->local()] = ValueSource(ValueInJSStack);
463
            return;
541
            return;
464
        }
542
        }
465
        
543
        
466
        m_out.set(value, m_locals64.operand(variable->local()));
544
        m_out.set(value, m_locals64.operand(variable->local()));
467
        if (needsFlushing)
545
        if (needsFlushing) {
468
            m_out.store64(value, addressFor(variable->local()));
546
            m_out.store64(value, addressFor(variable->local()));
547
            m_valueSources[variable->local()] = ValueSource(ValueInJSStack);
548
        }
549
    }
550
    
551
    void compileMovHint()
552
    {
553
        observeMovHint(m_node);
554
    }
555
    
556
    void compileZombieHint()
557
    {
558
        VariableAccessData* data = m_node->variableAccessData();
559
        m_lastSetOperand = data->local();
560
        m_valueSources[data->local()] = ValueSource(SourceIsDead);
469
    }
561
    }
470
    
562
    
471
    void compileMovHintAndCheck()
563
    void compileMovHintAndCheck()
472
    {
564
    {
473
        // FIXME: Handle the MovHint for OSR.
565
        observeMovHint(m_node);
474
        // https://bugs.webkit.org/show_bug.cgi?id=113623
475
        speculate(m_node->child1());
566
        speculate(m_node->child1());
476
    }
567
    }
477
    
568
    
Lines 865-870 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec12
865
        }
956
        }
866
    }
957
    }
867
    
958
    
959
    void use(Node*, Edge edge)
960
    {
961
        HashMap<Node*, unsigned>::iterator iter = m_timeToLive->find(edge.node());
962
        ASSERT(iter != m_timeToLive->end());
963
        ASSERT(iter->value);
964
        iter->value--;
965
    }
966
    
967
    void observeMovHint(Node* node)
968
    {
969
        ASSERT(node->containsMovHint());
970
        ASSERT(node->op() != ZombieHint);
971
        
972
        int operand = node->local();
973
        
974
        m_lastSetOperand = operand;
975
        m_valueSources[operand] = ValueSource(node->child1().node());
976
    }
977
    
868
    void speculateBackward(ExitKind, LValue, Node*, LValue failCondition)
978
    void speculateBackward(ExitKind, LValue, Node*, LValue failCondition)
869
    {
979
    {
870
        LBasicBlock failCase = m_out.newBlock();
980
        LBasicBlock failCase = m_out.newBlock();
Lines 1165-1175 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec13
1165
    HashMap<Node*, LValue> m_jsValueValues;
1275
    HashMap<Node*, LValue> m_jsValueValues;
1166
    HashMap<Node*, LValue> m_booleanValues;
1276
    HashMap<Node*, LValue> m_booleanValues;
1167
    HashMap<Node*, LValue> m_storageValues;
1277
    HashMap<Node*, LValue> m_storageValues;
1278
    HashMap<Node*, unsigned> m_timeToLive;
1168
    
1279
    
1169
    Operands<LValue> m_localsBoolean;
1280
    Operands<LValue> m_localsBoolean;
1170
    Operands<LValue> m_locals32;
1281
    Operands<LValue> m_locals32;
1171
    Operands<LValue> m_locals64;
1282
    Operands<LValue> m_locals64;
1172
    
1283
    
1284
    Operands<ValueSource> m_valueSources;
1285
    
1173
    AbstractState m_state;
1286
    AbstractState m_state;
1174
    BasicBlock* m_highBlock;
1287
    BasicBlock* m_highBlock;
1175
    BasicBlock* m_nextHighBlock;
1288
    BasicBlock* m_nextHighBlock;
- Source/JavaScriptCore/ftl/FTLOSRExit.cpp +98 lines
Line 0 Source/JavaScriptCore/ftl/FTLOSRExit.cpp_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "FTLOSRExit.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
OSRExit::OSRExit(
34
    ExitKind exitKind, ValueFormat profileValueFormat,
35
    MethodOfGettingAValueProfile valueProfile, CodeOrigin codeOrigin, int lastSetOperand,
36
    LValue exitStubAddress)
37
    : OSRExitBase(exitKind, codeOrigin)
38
    , m_profileValueFormat(profileValueFormat)
39
    , m_valueProfile(valueProfile)
40
    , m_codeOrigin(codeOrigin)
41
    , m_patchableCodeOffset(0)
42
    , m_exitStubAddress(exitStubAddress)
43
    , m_lastSetOperand(lastSetOperand)
44
{
45
}
46
47
void OSRExit::setPatchableCodeOffset(MacroAssembler::PatchableJump jump)
48
{
49
    m_patchableCodeOffset = jump.m_jump.m_label.m_offset;
50
}
51
52
CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* ftlCodeBlock) const
53
{
54
    return CodeLocationJump(
55
        reinterpret_cast<char*>(
56
            ftlCodeBlock->getJITCode()->ftl()->exitThunks().dataLocation()) +
57
        m_patchableCodeOffset);
58
}
59
60
void OSRExit::convertToForward(
61
    DFG::BasicBlock* block, DFG::Node* currentNode, unsigned nodeIndex,
62
    const FormattedValue &value, Vector<LValue>& arguments)
63
{
64
    Node* node;
65
    Node* lastMovHint;
66
    doSearchForForwardConversion(block, currentNode, nodeIndex, !!valueRecovery);
67
68
    ASSERT(node->codeOrigin != currentNode->codeOrigin);
69
    
70
    m_codeOrigin = node->codeOrigin;
71
    
72
    if (!value)
73
        return;
74
    
75
    int overriddenOperand = lastMovHint->local();
76
    m_lastSetOperand = overriddenOperand;
77
    
78
    // Is the value for this operand being passed as an argument to the exit, or is
79
    // it something else? If it's an argument already, then replace that argument;
80
    // otherwise add another argument.
81
    if (m_values[overriddenOperand].isArgument()) {
82
        ExitArgument argument = m_values[overriddenOperand].exitArgument();
83
        arguments[exitArgument.argument()] = value.value();
84
        m_values[overriddenOperand] = ExitValue::exitArgument(
85
            exitArgument.withFormat(value.format()));
86
        return;
87
    }
88
    
89
    unsigned argument = arguments.size();
90
    arguments.append(value.value());
91
    m_values[m_lastSetOperand] = ExitValue::exitArgument(
92
        ExitArgument(value.format(), argument));
93
}
94
95
} } // namespace JSC::FTL
96
97
#endif // ENABLE(FTL_JIT)
98
- Source/JavaScriptCore/ftl/FTLOSRExit.h +180 lines
Line 0 Source/JavaScriptCore/ftl/FTLOSRExit.h_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef FTLOSRExit_h
27
#define FTLOSRExit_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "CodeOrigin.h"
34
#include "DFGExitProfile.h"
35
#include "DFGOSRExitBase.h"
36
#include "FTLAbbreviations.h"
37
#include "FTLExitValue.h"
38
#include "MethodOfGettingAValueProfile.h"
39
#include "Operands.h"
40
#include "ValueProfile.h"
41
42
namespace JSC { namespace FTL {
43
44
// Tracks one OSR exit site within the FTL JIT. OSR exit in FTL works by deconstructing
45
// the crazy that is OSR down to simple SSA CFG primitives that any compiler backend
46
// (including of course LLVM) can grok and do meaningful things to. Except for
47
// watchpoint-based exits, which haven't yet been implemented (see webkit.org/b/113647),
48
// an exit is just a conditional branch in the emitted code where one destination is the
49
// continuation and the other is a basic block that performs a no-return tail-call to an
50
// exit thunk. This thunk takes as its arguments the live non-constant
51
// not-already-accounted-for bytecode state. To appreciate how this works consider the
52
// following JavaScript program, and its lowering down to LLVM IR including the relevant
53
// exits:
54
//
55
// function foo(o) {
56
//     var a = o.a; // predicted int
57
//     var b = o.b;
58
//     var c = o.c; // NB this is dead
59
//     a = a | 5; // our example OSR exit: need to check if a is an int
60
//     return a + b;
61
// }
62
//
63
// Just consider the "a | 5". In the DFG IR, this looks like:
64
//
65
// BitOr(Check:Int32:@a, Int32:5)
66
//
67
// Where @a is the node for the GetLocal node that gets the value of the 'a' variable.
68
// Conceptually, this node can be further broken down to the following (note that this
69
// particular lowering never actually happens - we skip this step and go straight to
70
// LLVM IR - but it's still useful to see this):
71
//
72
// exitIf(@a is not int32);
73
// continuation;
74
//
75
// Where 'exitIf()' is a function that will exit if the argument is true, and
76
// 'continuation' is the stuff that we will do after the exitIf() check. (Note that
77
// FTL refers to 'exitIf()' as 'speculate()', which is in line with DFG terminology.)
78
// This then gets broken down to the following LLVM IR, assuming that %0 is the LLVM
79
// value corresponding to variable 'a', and %1 is the LLVM value for variable 'b':
80
//
81
//   %2 = ... // the predictate corresponding to '@a is not int32'
82
//   br i1 %2, label %3, label %4
83
// ; <label>:3
84
//   call void exitThunk1(%0, %1) // pass 'a' and 'b', since they're both live-in-bytecode
85
//   unreachable
86
// ; <label>:4
87
//   ... // code for the continuation
88
//
89
// Where 'exitThunk1' is the IR to get the exit thunk for *this* OSR exit. Each OSR
90
// exit will appear to LLVM to have a distinct exit thunk.
91
//
92
// Note that this didn't have to pass '5', 'o', or 'c' to the exit thunk. 5 is a
93
// constant and the DFG already knows that, and can already tell the OSR exit machinery
94
// what that contant is and which bytecode variables (if any) it needs to be dropped
95
// into. This is conveyed to the exit statically, via the OSRExit data structure below.
96
// See the code for ExitValue for details. 'o' is an argument, and arguments are always
97
// "flushed" - if you never assign them then their values are still in the argument
98
// stack slots, and if you do assign them then we eagerly store them into those slots.
99
// 'c' is dead in bytecode, and the DFG knows this; we statically tell the exit thunk
100
// that it's dead and don't have to pass anything. The exit thunk will "initialize" its
101
// value to Undefined.
102
//
103
// This approach to OSR exit has a number of virtues:
104
//
105
// - It is an entirely unsurprising representation for a compiler that already groks
106
//   CFG-like IRs for C-like languages. All existing analyses and transformations just
107
//   work.
108
//
109
// - It lends itself naturally to modern approaches to code motion. For example, you
110
//   could sink operations from above the exit to below it, if you just duplicate the
111
//   operation into the OSR exit block. This is both legal and desirable. It works
112
//   because the backend sees the OSR exit block as being no different than any other,
113
//   and LLVM already supports sinking if it sees that a value is only partially used.
114
//   Hence there exists a value that dominates the exit but is only used by the exit
115
//   thunk and not by the continuation, sinking ought to kick in for that value.
116
//   Hoisting operations from below it to above it is also possible, for similar
117
//   reasons.
118
//
119
// - The no-return tail-call to the OSR exit thunk can be subjected to specialized
120
//   code-size reduction optimizations, though this is optional. For example, instead
121
//   of actually emitting a call along with all that goes with it (like placing the
122
//   arguments into argument position), the backend could choose to simply inform us
123
//   where it had placed the arguments and expect the callee (i.e. the exit thunk) to
124
//   figure it out from there. It could also tell us what we need to do to pop stack,
125
//   although again, it doesn't have to; it could just emit that code normally. Though
126
//   we don't support this yet, we could; the only thing that would change on our end
127
//   is that we'd need feedback from the backend about the location of the arguments
128
//   and a description of the things that need to be done to pop stack. This would
129
//   involve switching the m_values array to use something more akin to ValueRecovery
130
//   rather than the current ExitValue, albeit possibly with some hacks to better
131
//   understand the kinds of places where the LLVM backend would put values.
132
//
133
// - It could be extended to allow the backend to do its own exit hoisting, by using
134
//   intrinsics (or meta-data, or something) to inform the backend that it's safe to
135
//   make the predicate passed to 'exitIf()' more truthy.
136
//
137
// - It could be extended to support watchpoints (see webkit.org/b/113647) by making
138
//   the predicate passed to 'exitIf()' be an intrinsic that the backend knows to be
139
//   true at compile-time. The backend could then turn the conditional branch into a
140
//   replaceable jump, much like the DFG does.
141
142
struct OSRExit : public OSRExitBase {
143
    OSRExit(
144
        ExitKind, ValueFormat profileValueFormat, MethodOfGettingAValueProfile,
145
        CodeOrigin, int lastSetOperand, LValue exitStubAddress);
146
    
147
    MacroAssemblerCodeRef m_code;
148
    
149
    // The first argument to the exit call may be a value we wish to profile.
150
    // If that's the case, the format will be not Invalid and we'll have a
151
    // method of getting a value profile. Note that all of the ExitArgument's
152
    // are already aware of this possible off-by-one, so there is no need to
153
    // correct them.
154
    ValueFormat m_profileValueFormat;
155
    MethodOfGettingAValueProfile m_valueProfile;
156
    
157
    CodeOrigin m_codeOrigin;
158
    
159
    // Offset within the exit stubs of the stub for this exit.
160
    unsigned m_patchableCodeOffset;
161
    LValue m_exitStubAddress; // FIXME: Move this out of OSRExit, so it doesn't pollute CodeBlock.
162
    
163
    int m_lastSetOperand;
164
    
165
    Operands<ExitValue> m_values;
166
    
167
    void setPatchableCodeOffset(MacroAssembler::PatchableJump);
168
    CodeLocationJump codeLocationForRepatch(CodeBlock* ftlCodeBlock) const;
169
    
170
    void convertToForward(
171
        DFG::BasicBlock*, DFG::Node* currentNode, unsigned nodeIndex,
172
        const FormattedValue&, Vector<LValue>& arguments);
173
};
174
175
} } // namespace JSC::FTL
176
177
#endif // ENABLE(FTL_JIT)
178
179
#endif // FTLOSRExit_h
180
- Source/JavaScriptCore/ftl/FTLValueFormat.cpp +64 lines
Line 0 Source/JavaScriptCore/ftl/FTLValueFormat.cpp_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "FTLValueFormat.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace WTF {
32
33
using namespace JSC::FTL;
34
35
void printInternal(PrintStream& out, ValueFormat format)
36
{
37
    switch (format) {
38
    case InvalidValueFormat:
39
        out.print("Invalid");
40
        return;
41
    case ValueFormatInt32:
42
        out.print("Int32");
43
        return;
44
    case ValueFormatUInt32:
45
        out.print("UInt32");
46
        return;
47
    case ValueFormatBoolean:
48
        out.print("Boolean");
49
        return;
50
    case ValueFormatJSValue:
51
        out.print("JSValue");
52
        return;
53
    case ValueFormatDouble:
54
        out.print("Double");
55
        return;
56
    }
57
    
58
    RELEASE_ASSERT_NOT_REACHED();
59
}
60
61
} // namespace WTF
62
63
#endif // ENABLE(FTL_JIT)
64
- Source/JavaScriptCore/ftl/FTLValueFormat.h +60 lines
Line 0 Source/JavaScriptCore/ftl/FTLValueFormat.h_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef FTLValueFormat_h
27
#define FTLValueFormat_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include <wtf/PrintStream.h>
34
35
namespace JSC { namespace FTL {
36
37
// Note that this is awkwardly similar to DataFormat in other parts of JSC, except that
38
// unlike DataFormat and like ValueRecovery, it distinguishes between UInt32 and Int32.
39
40
enum ValueFormat {
41
    InvalidValueFormat,
42
    ValueFormatInt32,
43
    ValueFormatUInt32,
44
    ValueFormatBoolean,
45
    ValueFormatJSValue,
46
    ValueFormatDouble
47
};
48
49
} } // namespace JSC::FTL
50
51
namespace WTF {
52
53
void printInternal(PrintStream&, JSC::FTL::ValueFormat);
54
55
} // namespace WTF
56
57
#endif // ENABLE(FTL_JIT)
58
59
#endif // FTLValueFormat_h
60
- Source/JavaScriptCore/ftl/FTLValueSource.cpp +77 lines
Line 0 Source/JavaScriptCore/ftl/FTLValueSource.cpp_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "FTLValueSource.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
void ValueSource::dump(PrintStream& out) const
34
{
35
    switch (kind()) {
36
    case SourceNotSet:
37
        out.print("SourceNotSet");
38
        return;
39
    case ValueInJSStack:
40
        out.print("ValueInJSStack");
41
        return;
42
    case Int32InJSStack:
43
        out.print("Int32InJSStack");
44
        return;
45
    case DoubleInJSStack:
46
        out.print("DoubleInJSStack");
47
        return;
48
    case ValueInLocals:
49
        out.print("ValueInLocals");
50
        return;
51
    case Int32InLocals:
52
        out.print("Int32InLocals");
53
        return;
54
    case BooleanInLocals:
55
        out.print("BooleanInLocals");
56
        return;
57
    case DoubleInLocals:
58
        out.print("DoubleInLocals");
59
        return;
60
    case ArgumentsSource:
61
        out.print("ArgumentsSource");
62
        return;
63
    case SourceIsDead:
64
        out.print("SourceIsDead");
65
        return;
66
    case HaveNode:
67
        out.print("Node(", node(), ")");
68
        return;
69
    }
70
    
71
    RELEASE_ASSERT_NOT_REACHED();
72
}
73
74
} } // namespace JSC::FTL
75
76
#endif // ENABLE(FTL_JIT)
77
- Source/JavaScriptCore/ftl/FTLValueSource.h +92 lines
Line 0 Source/JavaScriptCore/ftl/FTLValueSource.h_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef FTLValueSource_h
27
#define FTLValueSource_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
namespace JSC { namespace FTL {
34
35
enum ValueSourceKind {
36
    SourceNotSet,
37
    ValueInJSStack,
38
    Int32InJSStack,
39
    DoubleInJSStack,
40
    ValueInLocals,
41
    Int32InLocals,
42
    BooleanInLocals,
43
    DoubleInLocals,
44
    ArgumentsSource,
45
    SourceIsDead,
46
    HaveNode
47
};
48
49
class ValueSource {
50
public:
51
    ValueSource()
52
        : m_value(SourceNotSet)
53
    {
54
    }
55
    
56
    explicit ValueSource(ValueSourceKind kind)
57
        : m_value(kind)
58
    {
59
    }
60
    
61
    explicit ValueSource(DFG::Node* node)
62
        : m_value(bitwise_cast<uintptr_t>(node))
63
    {
64
    }
65
    
66
    ValueSourceKind() kind() const
67
    {
68
        if (m_value < static_cast<uintptr_t>(HaveNode))
69
            return static_cast<ValueSourceKind>(m_value);
70
        return HaveNode;
71
    }
72
    
73
    bool operator!() const { return kind() != SourceNotSet; }
74
    
75
    DFG::Node* node() const
76
    {
77
        ASSERT(kind() == HaveNode);
78
        return bitwise_cast<DFG::Node*>(m_value);
79
    }
80
    
81
    void dump(PrintStream&) const;
82
83
private:
84
    uintptr_t m_value;
85
};
86
87
} } // namespace JSC::FTL
88
89
#endif // ENABLE(FTL_JIT)
90
91
#endif // FTLValueSource_h
92

Return to Bug 113623