| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog +235 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2013-04-10  Filip Pizlo  <fpizlo@apple.com>
2
3
        fourthTier: 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
        * assembler/AbstractMacroAssembler.h:
11
        (Address):
12
        (JSC::AbstractMacroAssembler::Address::withOffset):
13
        * assembler/LinkBuffer.h:
14
        (JSC::LinkBuffer::offsetOf):
15
        (LinkBuffer):
16
        * dfg/DFGAbstractState.cpp:
17
        (JSC::DFG::AbstractState::initialize):
18
        * dfg/DFGGPRInfo.h:
19
        (GPRInfo):
20
        * dfg/DFGMinifiedNode.h:
21
        (JSC::DFG::belongsInMinifiedGraph):
22
        * dfg/DFGNodeType.h:
23
        (JSC::DFG::needsOSRBackwardRewiring):
24
        (DFG):
25
        (JSC::DFG::needsOSRForwardRewiring):
26
        * dfg/DFGOSRExit.cpp:
27
        (JSC::DFG::OSRExit::OSRExit):
28
        (DFG):
29
        (JSC::DFG::OSRExit::convertToForward):
30
        * dfg/DFGOSRExit.h:
31
        (OSRExit):
32
        * dfg/DFGOSRExitBase.cpp: Added.
33
        (DFG):
34
        (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
35
        (JSC::DFG::OSRExitBase::doSearchForForwardConversion):
36
        * dfg/DFGOSRExitBase.h: Added.
37
        (DFG):
38
        (JSC::DFG::OSRExitBase::OSRExitBase):
39
        (OSRExitBase):
40
        (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
41
        * dfg/DFGOSRExitCompiler.cpp:
42
        * dfg/DFGOSRExitCompilerCommon.cpp:
43
        (JSC::DFG::handleExitCounts):
44
        (JSC::DFG::reifyInlinedCallFrames):
45
        (JSC::DFG::adjustAndJumpToTarget):
46
        * dfg/DFGOSRExitCompilerCommon.h:
47
        (DFG):
48
        * dfg/DFGOSRExitPreparation.cpp: Added.
49
        (DFG):
50
        (JSC::DFG::prepareCodeOriginForOSRExit):
51
        * dfg/DFGOSRExitPreparation.h: Added.
52
        (DFG):
53
        * dfg/DFGSpeculativeJIT.cpp:
54
        (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
55
        * dfg/DFGValueSource.h:
56
        (JSC::DFG::ValueSource::forSpeculation):
57
        * dfg/DFGVariableEventStream.cpp:
58
        (JSC::DFG::VariableEventStream::reconstruct):
59
        * ftl/FTLAbbreviations.h:
60
        (FTL):
61
        (JSC::FTL::functionType):
62
        (JSC::FTL::typeOf):
63
        (JSC::FTL::buildCall):
64
        (JSC::FTL::setTailCall):
65
        * ftl/FTLCArgumentGetter.cpp: Added.
66
        (FTL):
67
        (JSC::FTL::CArgumentGetter::loadNextAndBox):
68
        * ftl/FTLCArgumentGetter.h: Added.
69
        (FTL):
70
        (JSC::FTL::isArgumentRegister):
71
        (CArgumentGetter):
72
        (JSC::FTL::CArgumentGetter::CArgumentGetter):
73
        (JSC::FTL::CArgumentGetter::loadNext8):
74
        (JSC::FTL::CArgumentGetter::loadNext32):
75
        (JSC::FTL::CArgumentGetter::loadNext64):
76
        (JSC::FTL::CArgumentGetter::loadNextPtr):
77
        (JSC::FTL::CArgumentGetter::loadNextDouble):
78
        (JSC::FTL::CArgumentGetter::nextAddress):
79
        * ftl/FTLExitArgument.cpp: Added.
80
        (FTL):
81
        (JSC::FTL::ExitArgument::dump):
82
        * ftl/FTLExitArgument.h: Added.
83
        (FTL):
84
        (ExitArgumentRepresentation):
85
        (ExitArgument):
86
        (JSC::FTL::ExitArgument::ExitArgument):
87
        (JSC::FTL::ExitArgument::operator!):
88
        (JSC::FTL::ExitArgument::format):
89
        (JSC::FTL::ExitArgument::argument):
90
        (JSC::FTL::ExitArgument::withFormat):
91
        (JSC::FTL::ExitArgument::representation):
92
        * ftl/FTLExitArgumentForOperand.cpp: Added.
93
        (FTL):
94
        (JSC::FTL::ExitArgumentForOperand::dump):
95
        * ftl/FTLExitArgumentForOperand.h: Added.
96
        (FTL):
97
        (ExitArgumentForOperand):
98
        (JSC::FTL::ExitArgumentForOperand::ExitArgumentForOperand):
99
        (JSC::FTL::ExitArgumentForOperand::operator!):
100
        (JSC::FTL::ExitArgumentForOperand::exitArgument):
101
        (JSC::FTL::ExitArgumentForOperand::operand):
102
        (JSC::FTL::lesserArgumentIndex):
103
        * ftl/FTLExitArgumentList.h: Added.
104
        (FTL):
105
        * ftl/FTLExitThunkGenerator.cpp: Added.
106
        (FTL):
107
        (JSC::FTL::ExitThunkGenerator::ExitThunkGenerator):
108
        (JSC::FTL::ExitThunkGenerator::~ExitThunkGenerator):
109
        (JSC::FTL::ExitThunkGenerator::emitThunk):
110
        * ftl/FTLExitThunkGenerator.h: Added.
111
        (FTL):
112
        (ExitThunkGenerator):
113
        * ftl/FTLExitValue.cpp: Added.
114
        (FTL):
115
        (JSC::FTL::ExitValue::dump):
116
        * ftl/FTLExitValue.h: Added.
117
        (FTL):
118
        (ExitValue):
119
        (JSC::FTL::ExitValue::ExitValue):
120
        (JSC::FTL::ExitValue::operator!):
121
        (JSC::FTL::ExitValue::dead):
122
        (JSC::FTL::ExitValue::inJSStack):
123
        (JSC::FTL::ExitValue::inJSStackAsInt32):
124
        (JSC::FTL::ExitValue::inJSStackAsDouble):
125
        (JSC::FTL::ExitValue::constant):
126
        (JSC::FTL::ExitValue::exitArgument):
127
        (JSC::FTL::ExitValue::kind):
128
        (JSC::FTL::ExitValue::isDead):
129
        (JSC::FTL::ExitValue::isInJSStackSomehow):
130
        (JSC::FTL::ExitValue::isConstant):
131
        (JSC::FTL::ExitValue::isArgument):
132
        * ftl/FTLFormattedValue.h:
133
        (FTL):
134
        (JSC::FTL::noValue):
135
        (JSC::FTL::int32Value):
136
        (JSC::FTL::uInt32Value):
137
        (JSC::FTL::booleanValue):
138
        (JSC::FTL::jsValueValue):
139
        (JSC::FTL::doubleValue):
140
        * ftl/FTLJITCode.cpp:
141
        (JSC::FTL::JITCode::initializeExitThunks):
142
        (FTL):
143
        (JSC::FTL::JITCode::exitThunks):
144
        * ftl/FTLJITCode.h:
145
        (JITCode):
146
        * ftl/FTLLowerDFGToLLVM.cpp:
147
        (FTL):
148
        (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
149
        (JSC::FTL::LowerDFGToLLVM::lower):
150
        (JSC::FTL::LowerDFGToLLVM::transferAndCheckArguments):
151
        (JSC::FTL::LowerDFGToLLVM::compileBlock):
152
        (JSC::FTL::LowerDFGToLLVM::compileNode):
153
        (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
154
        (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
155
        (LowerDFGToLLVM):
156
        (JSC::FTL::LowerDFGToLLVM::compileMovHint):
157
        (JSC::FTL::LowerDFGToLLVM::compileZombieHint):
158
        (JSC::FTL::LowerDFGToLLVM::compileMovHintAndCheck):
159
        (JSC::FTL::LowerDFGToLLVM::compileAdd):
160
        (JSC::FTL::LowerDFGToLLVM::compileArithSub):
161
        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
162
        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
163
        (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
164
        (JSC::FTL::LowerDFGToLLVM::compileCheckStructure):
165
        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
166
        (JSC::FTL::LowerDFGToLLVM::speculateBackward):
167
        (JSC::FTL::LowerDFGToLLVM::speculateForward):
168
        (JSC::FTL::LowerDFGToLLVM::speculate):
169
        (JSC::FTL::LowerDFGToLLVM::backwardTypeCheck):
170
        (JSC::FTL::LowerDFGToLLVM::forwardTypeCheck):
171
        (JSC::FTL::LowerDFGToLLVM::typeCheck):
172
        (JSC::FTL::LowerDFGToLLVM::appendTypeCheck):
173
        (JSC::FTL::LowerDFGToLLVM::lowInt32):
174
        (JSC::FTL::LowerDFGToLLVM::lowCell):
175
        (JSC::FTL::LowerDFGToLLVM::lowBoolean):
176
        (JSC::FTL::LowerDFGToLLVM::speculateObject):
177
        (JSC::FTL::LowerDFGToLLVM::isLive):
178
        (JSC::FTL::LowerDFGToLLVM::use):
179
        (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
180
        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
181
        (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
182
        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
183
        (JSC::FTL::LowerDFGToLLVM::addExitArgument):
184
        (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlock):
185
        (JSC::FTL::LowerDFGToLLVM::observeMovHint):
186
        * ftl/FTLOSRExit.cpp: Added.
187
        (FTL):
188
        (JSC::FTL::OSRExit::OSRExit):
189
        (JSC::FTL::OSRExit::codeLocationForRepatch):
190
        (JSC::FTL::OSRExit::convertToForward):
191
        * ftl/FTLOSRExit.h: Added.
192
        (FTL):
193
        (OSRExit):
194
        * ftl/FTLOSRExitCompilationInfo.h: Added.
195
        (FTL):
196
        (JSC::FTL::OSRExitCompilationInfo::OSRExitCompilationInfo):
197
        (OSRExitCompilationInfo):
198
        * ftl/FTLOSRExitCompiler.cpp: Added.
199
        (FTL):
200
        (JSC::FTL::compileStub):
201
        (JSC::FTL::compileFTLOSRExit):
202
        * ftl/FTLOSRExitCompiler.h: Added.
203
        (FTL):
204
        * ftl/FTLOutput.h:
205
        (JSC::FTL::Output::intToPtr):
206
        (JSC::FTL::Output::load):
207
        (JSC::FTL::Output::store):
208
        (Output):
209
        (JSC::FTL::Output::call):
210
        (JSC::FTL::Output::convertToTailCall):
211
        * ftl/FTLState.h:
212
        (State):
213
        * ftl/FTLThunks.cpp: Added.
214
        (FTL):
215
        (JSC::FTL::osrExitGenerationThunkGenerator):
216
        * ftl/FTLThunks.h: Added.
217
        (JSC):
218
        (FTL):
219
        * ftl/FTLValueFormat.cpp: Added.
220
        (WTF):
221
        (WTF::printInternal):
222
        * ftl/FTLValueFormat.h: Added.
223
        (FTL):
224
        (WTF):
225
        * ftl/FTLValueSource.cpp: Added.
226
        (FTL):
227
        (JSC::FTL::ValueSource::dump):
228
        * ftl/FTLValueSource.h: Added.
229
        (FTL):
230
        (ValueSource):
231
        (JSC::FTL::ValueSource::ValueSource):
232
        (JSC::FTL::ValueSource::kind):
233
        (JSC::FTL::ValueSource::operator!):
234
        (JSC::FTL::ValueSource::node):
235
1
2013-04-09  Filip Pizlo  <fpizlo@apple.com>
236
2013-04-09  Filip Pizlo  <fpizlo@apple.com>
2
237
3
        fourthTier: DFG should provide utilities for common OSR exit tasks
238
        fourthTier: DFG should provide utilities for common OSR exit tasks
- Source/JavaScriptCore/assembler/AbstractMacroAssembler.h +5 lines
Lines 88-93 public: Source/JavaScriptCore/assembler/AbstractMacroAssembler.h_sec1
88
            , offset(offset)
88
            , offset(offset)
89
        {
89
        {
90
        }
90
        }
91
        
92
        Address withOffset(int32_t additionalOffset)
93
        {
94
            return Address(base, offset + additionalOffset);
95
        }
91
96
92
        RegisterID base;
97
        RegisterID base;
93
        int32_t offset;
98
        int32_t offset;
- Source/JavaScriptCore/assembler/LinkBuffer.h +5 lines
Lines 199-204 public: Source/JavaScriptCore/assembler/LinkBuffer.h_sec1
199
        return applyOffset(label.m_label).m_offset;
199
        return applyOffset(label.m_label).m_offset;
200
    }
200
    }
201
201
202
    unsigned offsetOf(PatchableJump jump)
203
    {
204
        return applyOffset(jump.m_jump.m_label).m_offset;
205
    }
206
202
    // Upon completion of all patching 'FINALIZE_CODE()' should be called once to
207
    // Upon completion of all patching 'FINALIZE_CODE()' should be called once to
203
    // complete generation of the code. Alternatively, call
208
    // complete generation of the code. Alternatively, call
204
    // finalizeCodeWithoutDisassembly() directly if you have your own way of
209
    // finalizeCodeWithoutDisassembly() directly if you have your own way of
- 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/DFGGPRInfo.h -1 / +1 lines
Lines 367-373 public: Source/JavaScriptCore/dfg/DFGGPRInfo.h_sec1
367
        static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3, argumentGPR4, argumentGPR5 };
367
        static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3, argumentGPR4, argumentGPR5 };
368
        return registerForIndex[index];
368
        return registerForIndex[index];
369
    }
369
    }
370
370
    
371
    static unsigned toIndex(GPRReg reg)
371
    static unsigned toIndex(GPRReg reg)
372
    {
372
    {
373
        ASSERT(reg != InvalidGPRReg);
373
        ASSERT(reg != InvalidGPRReg);
- 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 -53 / +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_codeOriginForExitProfile(m_codeOrigin)
44
    , m_recoveryIndex(recoveryIndex)
43
    , m_recoveryIndex(recoveryIndex)
45
    , m_watchpointIndex(std::numeric_limits<unsigned>::max())
44
    , m_watchpointIndex(std::numeric_limits<unsigned>::max())
46
    , m_kind(kind)
47
    , m_count(0)
48
    , m_streamIndex(streamIndex)
45
    , m_streamIndex(streamIndex)
49
    , m_lastSetOperand(jit->m_lastSetOperand)
46
    , m_lastSetOperand(jit->m_lastSetOperand)
50
{
47
{
Lines 73-129 void OSRExit::correctJump(LinkBuffer& li Source/JavaScriptCore/dfg/DFGOSRExit.cpp_sec2
73
    m_patchableCodeOffset = linkBuffer.offsetOf(label);
70
    m_patchableCodeOffset = linkBuffer.offsetOf(label);
74
}
71
}
75
72
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)
73
void OSRExit::convertToForward(BasicBlock* block, Node* currentNode, unsigned nodeIndex, const ValueRecovery& valueRecovery)
94
{
74
{
95
    // Check that either the current node is a SetLocal, or the preceding node was a
75
    Node* node;
96
    // SetLocal with the same code origin, or that we've provided a valueRecovery.
76
    Node* lastMovHint;
97
    if (!ASSERT_DISABLED
77
    doSearchForForwardConversion(block, currentNode, nodeIndex, !!valueRecovery);
98
        && !valueRecovery
78
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);
79
    ASSERT(node->codeOrigin != currentNode->codeOrigin);
80
    
127
    m_codeOrigin = node->codeOrigin;
81
    m_codeOrigin = node->codeOrigin;
128
    
82
    
129
    if (!valueRecovery)
83
    if (!valueRecovery)
- Source/JavaScriptCore/dfg/DFGOSRExit.h -17 / +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 93-114 struct OSRExit { Source/JavaScriptCore/dfg/DFGOSRExit.h_sec4
93
    MethodOfGettingAValueProfile m_valueProfile;
94
    MethodOfGettingAValueProfile m_valueProfile;
94
95
95
    unsigned m_patchableCodeOffset;
96
    unsigned m_patchableCodeOffset;
96
    CodeOrigin m_codeOrigin;
97
    CodeOrigin m_codeOriginForExitProfile;
98
    
97
    
99
    unsigned m_recoveryIndex;
98
    unsigned m_recoveryIndex;
100
    unsigned m_watchpointIndex;
99
    unsigned m_watchpointIndex;
101
    
100
    
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);
101
    void setPatchableCodeOffset(MacroAssembler::PatchableJump);
113
    MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
102
    MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
114
    CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
103
    CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
Lines 120-128 struct OSRExit { Source/JavaScriptCore/dfg/DFGOSRExit.h_sec5
120
    int m_lastSetOperand;
109
    int m_lastSetOperand;
121
    
110
    
122
    RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride;
111
    RefPtr<ValueRecoveryOverride> m_valueRecoveryOverride;
123
124
private:
125
    bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
126
};
112
};
127
113
128
struct SpeculationFailureDebugInfo {
114
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 +77 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_codeOrigin(origin)
46
        , m_codeOriginForExitProfile(origin)
47
    {
48
    }
49
    
50
    ExitKind m_kind;
51
    uint32_t m_count;
52
    
53
    CodeOrigin m_codeOrigin;
54
    CodeOrigin m_codeOriginForExitProfile;
55
56
    bool considerAddingAsFrequentExitSite(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock)
57
    {
58
        if (!m_count || !exitKindIsCountable(m_kind))
59
            return false;
60
        return considerAddingAsFrequentExitSiteSlow(dfgCodeBlock, profiledCodeBlock);
61
    }
62
    
63
    // Returns true if the forward conversion is really needed.
64
    bool doSearchForForwardConversion(
65
        BasicBlock*, Node* currentNode, unsigned nodeIndex, bool hasValueRecovery,
66
        Node*& nextBCNode, Node*& lastMovHint);
67
68
private:
69
    bool considerAddingAsFrequentExitSiteSlow(CodeBlock* dfgCodeBlock, CodeBlock* profiledCodeBlock);
70
};
71
72
} } // namespace JSC::DFG
73
74
#endif // ENABLE(DFG_JIT)
75
76
#endif // DFGOSRExitBase_h
77
- Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp -14 / +2 lines
Lines 31-36 Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp_sec1
31
#include "CallFrame.h"
31
#include "CallFrame.h"
32
#include "DFGCommon.h"
32
#include "DFGCommon.h"
33
#include "DFGJITCode.h"
33
#include "DFGJITCode.h"
34
#include "DFGOSRExitPreparation.h"
34
#include "LinkBuffer.h"
35
#include "LinkBuffer.h"
35
#include "Operations.h"
36
#include "Operations.h"
36
#include "RepatchBuffer.h"
37
#include "RepatchBuffer.h"
Lines 54-73 void compileOSRExit(ExecState* exec) Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp_sec2
54
    uint32_t exitIndex = globalData->osrExitIndex;
55
    uint32_t exitIndex = globalData->osrExitIndex;
55
    OSRExit& exit = codeBlock->getJITCode()->dfg()->osrExit[exitIndex];
56
    OSRExit& exit = codeBlock->getJITCode()->dfg()->osrExit[exitIndex];
56
    
57
    
57
    // Make sure all code on our inline stack is JIT compiled. This is necessary since
58
    prepareCodeOriginForOSRExit(exit.m_codeOrigin);
58
    // we may opt to inline a code block even before it had ever been compiled by the
59
    // JIT, but our OSR exit infrastructure currently only works if the target of the
60
    // OSR exit is JIT code. This could be changed since there is nothing particularly
61
    // hard about doing an OSR exit into the interpreter, but for now this seems to make
62
    // sense in that if we're OSR exiting from inlined code of a DFG code block, then
63
    // probably it's a good sign that the thing we're exiting into is hot. Even more
64
    // interestingly, since the code was inlined, it may never otherwise get JIT
65
    // compiled since the act of inlining it may ensure that it otherwise never runs.
66
    for (CodeOrigin codeOrigin = exit.m_codeOrigin; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
67
        static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())
68
            ->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)
69
            ->jitCompile(exec);
70
    }
71
    
59
    
72
    // Compute the value recoveries.
60
    // Compute the value recoveries.
73
    Operands<ValueRecovery> operands;
61
    Operands<ValueRecovery> operands;
- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp -3 / +3 lines
Lines 32-38 Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp_sec1
32
32
33
namespace JSC { namespace DFG {
33
namespace JSC { namespace DFG {
34
34
35
void handleExitCounts(CCallHelpers& jit, const OSRExit& exit)
35
void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
36
{
36
{
37
    jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
37
    jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
38
    
38
    
Lines 73-79 void handleExitCounts(CCallHelpers& jit, Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp_sec2
73
    doneAdjusting.link(&jit);
73
    doneAdjusting.link(&jit);
74
}
74
}
75
75
76
void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExit& exit)
76
void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
77
{
77
{
78
#if USE(JSVALUE64)
78
#if USE(JSVALUE64)
79
    ASSERT(jit.baselineCodeBlock()->getJITType() == JITCode::BaselineJIT);
79
    ASSERT(jit.baselineCodeBlock()->getJITType() == JITCode::BaselineJIT);
Lines 147-153 void reifyInlinedCallFrames(CCallHelpers Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp_sec3
147
#endif // USE(JSVALUE64) // ending the #else part, so directly above is the 32-bit part
147
#endif // USE(JSVALUE64) // ending the #else part, so directly above is the 32-bit part
148
}
148
}
149
149
150
void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExit& exit)
150
void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit)
151
{
151
{
152
    if (exit.m_codeOrigin.inlineCallFrame)
152
    if (exit.m_codeOrigin.inlineCallFrame)
153
        jit.addPtr(AssemblyHelpers::TrustedImm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
153
        jit.addPtr(AssemblyHelpers::TrustedImm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h -3 / +3 lines
Lines 35-43 Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h_sec1
35
35
36
namespace JSC { namespace DFG {
36
namespace JSC { namespace DFG {
37
37
38
void handleExitCounts(CCallHelpers&, const OSRExit&);
38
void handleExitCounts(CCallHelpers&, const OSRExitBase&);
39
void reifyInlinedCallFrames(CCallHelpers&, const OSRExit&);
39
void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&);
40
void adjustAndJumpToTarget(CCallHelpers&, const OSRExit&);
40
void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&);
41
41
42
} } // namespace JSC::DFG
42
} } // namespace JSC::DFG
43
43
- Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp +45 lines
Line 0 Source/JavaScriptCore/dfg/DFGOSRExitPreparation.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 "DFGOSRExitPreparation.h"
28
29
#if ENABLE(DFG_JIT)
30
31
namespace JSC { namespace DFG {
32
33
void prepareCodeOriginForOSRExit(CodeOrigin codeOrigin)
34
{
35
    for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) {
36
        static_cast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())
37
            ->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct)
38
            ->jitCompile(exec);
39
    }
40
}
41
42
} } // namespace JSC::DFG
43
44
#endif // ENABLE(DFG_JIT)
45
- Source/JavaScriptCore/dfg/DFGOSRExitPreparation.h +52 lines
Line 0 Source/JavaScriptCore/dfg/DFGOSRExitPreparation.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 DFGOSRExitPreparation_h
27
#define DFGOSRExitPreparation_h
28
29
#if ENABLE(DFG_JIT)
30
31
#include "CodeOrigin.h"
32
33
namespace JSC { namespace DFG {
34
35
// Make sure all code on our inline stack is JIT compiled. This is necessary since
36
// we may opt to inline a code block even before it had ever been compiled by the
37
// JIT, but our OSR exit infrastructure currently only works if the target of the
38
// OSR exit is JIT code. This could be changed since there is nothing particularly
39
// hard about doing an OSR exit into the interpreter, but for now this seems to make
40
// sense in that if we're OSR exiting from inlined code of a DFG code block, then
41
// probably it's a good sign that the thing we're exiting into is hot. Even more
42
// interestingly, since the code was inlined, it may never otherwise get JIT
43
// compiled since the act of inlining it may ensure that it otherwise never runs.
44
void prepareCodeOriginForOSRExit(CodeOrigin codeOrigin);
45
46
} } // namespace JSC::DFG
47
48
#endif // ENABLE(DFG_JIT)
49
50
#endif // DFGOSRExitPreparation_h
51
52
- 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/FTLAbbreviations.h +14 lines
Lines 84-89 static inline LType functionType(LType r Source/JavaScriptCore/ftl/FTLAbbreviations.h_sec1
84
{
84
{
85
    return LLVMFunctionType(returnType, paramTypes, paramCount, variadicity == Variadic);
85
    return LLVMFunctionType(returnType, paramTypes, paramCount, variadicity == Variadic);
86
}
86
}
87
template<typename VectorType>
88
inline LType functionType(LType returnType, const VectorType& vector, Variadicity variadicity)
89
{
90
    return functionType(returnType, vector.begin(), vector.size(), variadicity);
91
}
87
static inline LType functionType(LType returnType, Variadicity variadicity = NotVariadic)
92
static inline LType functionType(LType returnType, Variadicity variadicity = NotVariadic)
88
{
93
{
89
    return functionType(returnType, 0, 0, variadicity);
94
    return functionType(returnType, 0, 0, variadicity);
Lines 98-103 static inline LType functionType(LType r Source/JavaScriptCore/ftl/FTLAbbreviations.h_sec2
98
    return functionType(returnType, paramTypes, 2, variadicity);
103
    return functionType(returnType, paramTypes, 2, variadicity);
99
}
104
}
100
105
106
static inline LType typeOf(LValue value) { return LLVMTypeOf(value); }
107
101
static inline unsigned mdKindID(const char* string) { return LLVMGetMDKindID(string, strlen(string)); }
108
static inline unsigned mdKindID(const char* string) { return LLVMGetMDKindID(string, strlen(string)); }
102
static inline LValue mdString(const char* string, unsigned length) { return LLVMMDString(string, length); }
109
static inline LValue mdString(const char* string, unsigned length) { return LLVMMDString(string, length); }
103
static inline LValue mdString(const char* string) { return mdString(string, strlen(string)); }
110
static inline LValue mdString(const char* string) { return mdString(string, strlen(string)); }
Lines 155-160 static inline LValue buildCall(LBuilder Source/JavaScriptCore/ftl/FTLAbbreviations.h_sec3
155
{
162
{
156
    return LLVMBuildCall(builder, function, args, numArgs, "");
163
    return LLVMBuildCall(builder, function, args, numArgs, "");
157
}
164
}
165
template<typename VectorType>
166
inline LValue buildCall(LBuilder builder, LValue function, const VectorType& vector)
167
{
168
    return buildCall(builder, function, vector.begin(), vector.size());
169
}
158
static inline LValue buildCall(LBuilder builder, LValue function)
170
static inline LValue buildCall(LBuilder builder, LValue function)
159
{
171
{
160
    return buildCall(builder, function, 0, 0);
172
    return buildCall(builder, function, 0, 0);
Lines 168-173 static inline LValue buildCall(LBuilder Source/JavaScriptCore/ftl/FTLAbbreviations.h_sec4
168
    LValue args[] = { arg1, arg2 };
180
    LValue args[] = { arg1, arg2 };
169
    return buildCall(builder, function, args, 2);
181
    return buildCall(builder, function, args, 2);
170
}
182
}
183
enum TailCallMode { IsNotTailCall, IsTailCall };
184
static inline void setTailCall(LValue call, TailCallMode mode) { LLVMSetTailCall(call, mode == IsTailCall); }
171
static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return LLVMBuildExtractValue(builder, aggVal, index, ""); }
185
static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return LLVMBuildExtractValue(builder, aggVal, index, ""); }
172
static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return LLVMBuildSelect(builder, condition, taken, notTaken, ""); }
186
static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return LLVMBuildSelect(builder, condition, taken, notTaken, ""); }
173
static inline LValue buildBr(LBuilder builder, LBasicBlock destination) { return LLVMBuildBr(builder, destination); }
187
static inline LValue buildBr(LBuilder builder, LBasicBlock destination) { return LLVMBuildBr(builder, destination); }
- Source/JavaScriptCore/ftl/FTLCArgumentGetter.cpp +99 lines
Line 0 Source/JavaScriptCore/ftl/FTLCArgumentGetter.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 "FTLCArgumentGetter.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
using namespace DFG;
34
35
void CArgumentGetter::loadNextAndBox(ValueFormat format, GPRReg destination, GPRReg scratch)
36
{
37
    if (scratch == InvalidGPRReg) {
38
        if (destination == GPRInfo::nonArgGPR0)
39
            scratch = GPRInfo::nonArgGPR1;
40
        else
41
            scratch = GPRInfo::nonArgGPR0;
42
    }
43
    
44
    switch (format) {
45
    case ValueFormatInt32: {
46
        loadNext32(destination);
47
        m_jit.or64(GPRInfo::tagTypeNumberRegister, destination);
48
        break;
49
    }
50
            
51
    case ValueFormatUInt32: {
52
        loadNext32(destination);
53
        MacroAssembler::Jump isInt = m_jit.branch32(
54
            MacroAssembler::GreaterThanOrEqual,
55
            destination, MacroAssembler::TrustedImm32(0));
56
            
57
        m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch);
58
        m_jit.convertInt32ToDouble(destination, FPRInfo::fpRegT0);
59
        m_jit.boxDouble(FPRInfo::fpRegT0, destination);
60
        m_jit.move64ToDouble(scratch, FPRInfo::fpRegT0);
61
            
62
        MacroAssembler::Jump done = m_jit.jump();
63
            
64
        isInt.link(&m_jit);
65
        m_jit.or64(GPRInfo::tagTypeNumberRegister, destination);
66
            
67
        done.link(&m_jit);
68
        break;
69
    }
70
            
71
    case ValueFormatBoolean: {
72
        loadNext8(destination);
73
        m_jit.or32(MacroAssembler::TrustedImm32(ValueFalse), destination);
74
        break;
75
    }
76
            
77
    case ValueFormatJSValue: {
78
        loadNext64(destination);
79
        break;
80
    }
81
            
82
    case ValueFormatDouble: {
83
        m_jit.moveDoubleTo64(FPRInfo::fpRegT0, scratch);
84
        loadNextDouble(FPRInfo::fpRegT0);
85
        m_jit.boxDouble(FPRInfo::fpRegT0, destination);
86
        m_jit.move64ToDouble(scratch, FPRInfo::fpRegT0);
87
        break;
88
    }
89
            
90
    default:
91
        RELEASE_ASSERT_NOT_REACHED();
92
        break;
93
    }
94
}
95
96
} } // namespace JSC::FTL
97
98
#endif // ENABLE(FTL_JIT)
99
- Source/JavaScriptCore/ftl/FTLCArgumentGetter.h +141 lines
Line 0 Source/JavaScriptCore/ftl/FTLCArgumentGetter.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 FTLCArgumentGetter_h
27
#define FTLCArgumentGetter_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "DFGAssemblyHelpers.h"
34
#include "FTLValueFormat.h"
35
36
namespace JSC { namespace FTL {
37
38
// This currently only understands how to get arguments on X86-64 cdecl. This is also
39
// not particularly efficient. It will generate some redundant moves.
40
41
template<typename RegisterKind>
42
bool isArgumentRegister(RegisterKind::RegisterType reg)
43
{
44
    for (unsigned i = 0; i < RegisterKind::numberOfArgumentRegisters; ++i) {
45
        if (RegisterKind::toArgumentRegister(i) == reg)
46
            return true;
47
    }
48
    return false;
49
}
50
51
class CArgumentGetter {
52
    using namespace DFG;
53
    
54
public:
55
    // Peek offset is the number of things on the stack below the first argument.
56
    // It will be 1 if you haven't pushed or popped after the call; i.e. the only
57
    // thing is the return address.
58
    CArgumentGetter(AssemblyHelpers& jit, int peekOffset = 1)
59
        : m_jit(jit)
60
        , m_peekOffset(peekOffset)
61
        , m_gprArgumentIndex(0)
62
        , m_fprArgumentIndex(0)
63
        , m_stackArgumentIndex(0)
64
    {
65
    }
66
    
67
    void loadNext8(GPRReg destination)
68
    {
69
        ASSERT(!isArgumentRegister<GPRInfo>(destination));
70
        if (m_gprArgumentIndex < GPRInfo::numberOfArgumentRegisters) {
71
            m_jit.move(GPRInfo::toArgumentRegister(m_gprArgumentIndex++), destination);
72
            return;
73
        }
74
        
75
        m_jit.load8(nextAddress(), destination);
76
    }
77
    
78
    void loadNext32(GPRReg destination)
79
    {
80
        ASSERT(!isArgumentRegister<GPRInfo>(destination));
81
        if (m_gprArgumentIndex < GPRInfo::numberOfArgumentRegisters) {
82
            m_jit.move(GPRInfo::toArgumentRegister(m_gprArgumentIndex++), destination);
83
            return;
84
        }
85
        
86
        m_jit.load32(nextAddress(), destination);
87
    }
88
    
89
    void loadNext64(GPRReg destination)
90
    {
91
        ASSERT(!isArgumentRegister<GPRInfo>(destination));
92
        if (m_gprArgumentIndex < GPRInfo::numberOfArgumentRegisters) {
93
            m_jit.move(GPRInfo::toArgumentRegister(m_gprArgumentIndex++), destination);
94
            return;
95
        }
96
        
97
        m_jit.load64(nextAddress(), destination);
98
    }
99
    
100
    void loadNextPtr(GPRReg destination)
101
    {
102
        loadNext64(destination);
103
    }
104
    
105
    void loadNextDouble(FPRReg destination)
106
    {
107
        ASSERT(
108
            !isArgumentRegister<FPRInfo>(destination)
109
            destination == FPRInfo::argumentFPR0);
110
        
111
        if (m_fprArgumentIndex < FPRInfo::numberOfArgumentRegisters) {
112
            m_jit.moveDouble(FPRInfo::toArgumentRegister(m_fprArgumentIndex++), destination);
113
            return;
114
        }
115
        
116
        m_jit.loadDouble(nextAddress(), destination);
117
    }
118
    
119
    void loadNextAndBox(ValueFormat format, GPRReg destination, GPRReg scratch = InvalidGPRReg);
120
121
private:
122
    MacroAssembler::Address nextAddress()
123
    {
124
        return MacroAssembler::Address(
125
            MacroAssembler::stackPointerRegister,
126
            (m_peekOffset + m_stackArgumentIndex++) * sizeof(void*));
127
    }
128
            
129
    AssemblyHelpers& m_jit;
130
    unsigned m_peekOffset;
131
    unsigned m_gprArgumentIndex;
132
    unsigned m_fprArgumentIndex;
133
    unsigned m_stackArgumentIndex;
134
};
135
136
} } // namespace JSC::FTL
137
138
#endif // ENABLE(FTL_JIT)
139
140
#endif // FTLCArgumentGetter_h
141
- 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/FTLExitArgumentForOperand.cpp +41 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.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 "FTLExitArgumentForOperand.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
void ExitArgumentForOperand::dump(PrintStream& out) const
34
{
35
    out.print(m_exitArgument, " for r", operand);
36
}
37
38
} } // namespace JSC::FTL
39
40
#endif // ENABLE(FTL_JIT)
41
- Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.h +72 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitArgumentForOperand.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 FTLExitArgumentForOperand_h
27
#define FTLExitArgumentForOperand_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLExitArgument.h"
34
35
namespace JSC { namespace FTL {
36
37
class ExitArgumentForOperand {
38
public:
39
    ExitArgumentForOperand()
40
        : m_operand(-1)
41
    {
42
    }
43
    
44
    ExitArgumentForOperand(ExitArgument exitArgument, int operand)
45
        : m_exitArgument(exitArgument)
46
        , m_operand(operand)
47
    {
48
    }
49
    
50
    bool operator!() const { return !m_exitArgument; }
51
    
52
    const ExitArgument& exitArgument() const { return m_exitArgument; }
53
    int operand() const { return m_operand; }
54
    
55
    void dump(PrintStream&) const;
56
    
57
private:
58
    ExitArgument m_exitArgument;
59
    int m_operand;
60
};
61
62
inline bool lesserArgumentIndex(ExitArgument a, ExitArgument b)
63
{
64
    return a.exitArgument().argument() < b.exitArgument().argument();
65
}
66
67
} } // namespace JSC::FTL
68
69
#endif // ENABLE(FTL_JIT)
70
71
#endif // FTLExitArgumentForOperand_h
72
- Source/JavaScriptCore/ftl/FTLExitArgumentList.h +45 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitArgumentList.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 FTLExitArgumentList_h
27
#define FTLExitArgumentList_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLAbbreviations.h"
34
#incldue <wtf/Vector.h>
35
36
namespace JSC { namespace FTL {
37
38
typedef Vector<LValue, 16> ExitArgumentList;
39
40
} } // namespace JSC::FTL
41
42
#endif // ENABLE(FTL_JIT)
43
44
#endif // FTLExitArgumentList_h
45
- Source/JavaScriptCore/ftl/FTLExitThunkGenerator.cpp +56 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitThunkGenerator.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 "FTLExitThunkGenerator.h"
28
29
#if ENABLE(FTL_JIT)
30
31
#include "FTLOSRExitCompilationInfo.h"
32
33
namespace JSC { namespace FTL {
34
35
using namespace JSC::DFG;
36
37
ExitThunkGenerator::ExitThunkGenerator(State& state)
38
    : CCallHelpers(&state.graph.m_globalData, state.graph.m_codeBlock)
39
{
40
}
41
42
ExitThunkGenerator::~ExitThunkGenerator()
43
{
44
}
45
46
void ExitThunkGenerator::emitThunk(unsigned index, OSRExitCompilationInfo& info)
47
{
48
    info.m_thunkLabel = label();
49
    move(TrustedImm32(index), GPRInfo::nonArgGRP0);
50
    info.m_thunkJump = patchableJump();
51
}
52
53
} } // namespace JSC::FTL
54
55
#endif // ENABLE(FTL_JIT)
56
- Source/JavaScriptCore/ftl/FTLExitThunkGenerator.h +53 lines
Line 0 Source/JavaScriptCore/ftl/FTLExitThunkGenerator.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 FTLExitThunkGenerator_h
27
#define FTLExitThunkGenerator_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "DFGCCallHelpers.h"
34
35
namespace JSC { namespace FTL {
36
37
class OSRExitCompilationInfo;
38
class State;
39
40
class ExitThunkGenerator : public CCallHelpers {
41
public:
42
    ExitThunkGenerator(State& state);
43
    ~ExitThunkGenerator();
44
    
45
    void emitThunk(unsigned index, OSRExitCompilationInfo&);
46
};
47
48
} } // namespace JSC::FTL
49
50
#endif // ENABLE(FTL_JIT)
51
52
#endif // FTLExitThunkGenerator_h
53
- 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 +151 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
    ExitValueInJSStackAsDouble
53
};
54
55
class ExitValue {
56
public:
57
    ExitValue()
58
        : m_kind(InvalidExitValue)
59
    {
60
    }
61
    
62
    bool operator!() const { return m_kind == InvalidExitValue; }
63
    
64
    static ExitValue dead()
65
    {
66
        ExitValue result;
67
        result.m_kind = ExitValueDead;
68
        return result;
69
    }
70
    
71
    static ExitValue inJSStack()
72
    {
73
        ExitValue result;
74
        result.m_kind = ExitValueInJSStack;
75
        return result;
76
    }
77
    
78
    static ExitValue inJSStackAsInt32()
79
    {
80
        ExitValue result;
81
        result.m_kind = ExitValueInJSStackAsInt32;
82
        return result;
83
    }
84
    
85
    static ExitValue inJSStackAsDouble()
86
    {
87
        ExitValue result;
88
        result.m_kind = ExitValueInJSStackAsDouble;
89
        return result;
90
    }
91
    
92
    static ExitValue constant(JSValue value)
93
    {
94
        ExitValue result;
95
        result.m_kind = ExitValueConstant;
96
        result.u.constant = JSValue::encode(value);
97
        return result;
98
    }
99
    
100
    static ExitValue exitArgument(const ExitArgument& argument)
101
    {
102
        ExitValue result;
103
        result.m_kind = ExitValueArgument;
104
        result.u.argument = argument.representation();
105
        return result;
106
    }
107
    
108
    ExitValueKind kind() const { return m_kind; }
109
    
110
    bool isDead() const { return kind() == ExitValueDead; }
111
    bool isInJSStackSomehow() const
112
    {
113
        switch (kind()) {
114
        case ExitValueInJSStack:
115
        case ExitValueInJSStackAsInt32:
116
        case ExitValueInJSStackAsDouble:
117
            return true;
118
        default:
119
            return false;
120
        }
121
    }
122
    bool isConstant() const { return kind() == ExitValueConstant; }
123
    bool isArgument() const { return kind() == ExitValueArgument; }
124
    
125
    ExitArgument exitArgument() const
126
    {
127
        ASSERT(isArgument());
128
        return ExitArgument(u.argument);
129
    }
130
    
131
    JSValue constant() const
132
    {
133
        ASSERT(isConstant());
134
        return JSValue::decode(u.constant);
135
    }
136
    
137
    void dump(PrintStream&) const;
138
    
139
private:
140
    ExitValueKind m_kind;
141
    union {
142
        ExitArgumentRepresentation argument;
143
        EncodedJSValue constant;
144
    } u;
145
};
146
147
} } // namespace JSC::FTL
148
149
#endif // ENABLE(FTL_JIT)
150
151
#endif // FTLExitValue_h
- Source/JavaScriptCore/ftl/FTLFormattedValue.h -12 / +8 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()
Lines 81-86 private: Source/JavaScriptCore/ftl/FTLFormattedValue.h_sec3
81
    LValue m_value;
70
    LValue m_value;
82
};
71
};
83
72
73
static inline FormattedValue noValue() { return FormattedValue(); }
74
static inline FormattedValue int32Value(LValue value) { return FormattedValue(ValueFormatInt32, value); }
75
static inline FormattedValue uInt32Value(LValue value) { return FormattedValue(ValueFormatUInt32, value); }
76
static inline FormattedValue booleanValue(LValue value) { return FormattedValue(ValueFormatBoolean, value); }
77
static inline FormattedValue jsValueValue(LValue value) { return FormattedValue(ValueFormatJSValue, value); }
78
static inline FormattedValue doubleValue(LValue value) { return FormattedValue(ValueFormatDouble, value); }
79
84
} } // namespace JSC::FTL
80
} } // namespace JSC::FTL
85
81
86
#endif // ENABLE(FTL_JIT)
82
#endif // ENABLE(FTL_JIT)
- 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 -79 / +487 lines
Lines 30-37 Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec1
30
30
31
#include "DFGAbstractState.h"
31
#include "DFGAbstractState.h"
32
#include "FTLAbstractHeapRepository.h"
32
#include "FTLAbstractHeapRepository.h"
33
#include "FTLExitThunkGenerator.h"
33
#include "FTLFormattedValue.h"
34
#include "FTLFormattedValue.h"
34
#include "FTLOutput.h"
35
#include "FTLOutput.h"
36
#include "FTLThunks.h"
35
#include "Operations.h"
37
#include "Operations.h"
36
38
37
namespace JSC { namespace FTL {
39
namespace JSC { namespace FTL {
Lines 41-47 using namespace DFG; Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec2
41
// Using this instead of typeCheck() helps to reduce the load on LLVM, by creating
43
// Using this instead of typeCheck() helps to reduce the load on LLVM, by creating
42
// significantly less dead code.
44
// significantly less dead code.
43
#define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) do { \
45
#define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) do { \
44
        LValue _ftc_lowValue = (lowValue);                              \
46
        FormattedValue _ftc_lowValue = (lowValue);                      \
45
        Edge _ftc_highValue = (highValue);                              \
47
        Edge _ftc_highValue = (highValue);                              \
46
        SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
48
        SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
47
        if (!m_state.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
49
        if (!m_state.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
Lines 57-62 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec3
57
        , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
59
        , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
58
        , m_locals32(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
60
        , m_locals32(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
59
        , m_locals64(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
61
        , m_locals64(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
62
        , m_valueSources(OperandsLike, state.graph.m_blocks[0]->variablesAtHead)
63
        , m_exitThunkGenerator(state)
60
        , m_state(state.graph)
64
        , m_state(state.graph)
61
    {
65
    {
62
    }
66
    }
Lines 80-93 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec4
80
            m_locals64[index] = buildAlloca(m_out.m_builder, m_out.int64);
84
            m_locals64[index] = buildAlloca(m_out.m_builder, m_out.int64);
81
        }
85
        }
82
        
86
        
87
        m_initialization = appendBasicBlock(m_ftlState.function);
88
        m_out.jump(m_initialization);
89
        m_out.appendTo(m_initialization);
90
        
83
        m_callFrame = m_out.param(0);
91
        m_callFrame = m_out.param(0);
84
        m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
92
        m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
85
        m_tagMask = m_out.constInt64(TagMask);
93
        m_tagMask = m_out.constInt64(TagMask);
86
        
94
        
87
        m_abortFunction = constIntToPtr(
88
            m_out.constIntPtr(abort),
89
            pointerType(functionType(m_out.voidType)));
90
        
91
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
95
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
92
            m_highBlock = m_graph.m_blocks[blockIndex].get();
96
            m_highBlock = m_graph.m_blocks[blockIndex].get();
93
            if (!m_highBlock)
97
            if (!m_highBlock)
Lines 98-111 public: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec5
98
        
102
        
99
        closeOverFlushedLocalOps();
103
        closeOverFlushedLocalOps();
100
104
101
        m_out.appendTo(m_prologue, m_blocks.get(m_graph.m_blocks[0].get()));
105
        m_out.appendTo(m_initialization, m_blocks.get(m_graph.m_blocks[0].get()));
102
106
103
        transferAndCheckArguments();
107
        transferAndCheckArguments();
104
        
108
        
105
        m_out.jump(m_blocks.get(m_graph.m_blocks[0].get()));
109
        // Leave the initialization block hanging, since we will add to it later.
106
        
110
        
107
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
111
        for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex)
108
            compileBlock(blockIndex);
112
            compileBlock(blockIndex);
113
        
114
        // And now complete the initialization block.
115
        linkOSRExitsAndCompleteInitializationBlock();
109
116
110
        if (verboseCompilationEnabled())
117
        if (verboseCompilationEnabled())
111
            m_ftlState.dumpState("after lowering");
118
            m_ftlState.dumpState("after lowering");
Lines 151-158 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec6
151
    
158
    
152
    void transferAndCheckArguments()
159
    void transferAndCheckArguments()
153
    {
160
    {
154
        // FIXME: Set up the OSR story here.
161
        // While checking arguments, everything is in the stack.
155
        // https://bugs.webkit.org/show_bug.cgi?id=113623
162
        for (unsigned i = size(); i--;)
163
            m_valueSources[i] = ValueSource(ValueInJSStack);
156
        
164
        
157
        for (int i = 0; i < m_graph.m_codeBlock->numParameters(); ++i) {
165
        for (int i = 0; i < m_graph.m_codeBlock->numParameters(); ++i) {
158
            Node* node = m_graph.m_arguments[i];
166
            Node* node = m_graph.m_arguments[i];
Lines 170-190 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec7
170
            if (variable->shouldUnboxIfPossible()) {
178
            if (variable->shouldUnboxIfPossible()) {
171
                RELEASE_ASSERT(!variable->shouldUseDoubleFormat());
179
                RELEASE_ASSERT(!variable->shouldUseDoubleFormat());
172
                
180
                
173
                SpeculatedType prediction = variable->prediction();
181
                SpeculatedType prediction = variable->argumentAwarePrediction();
174
                
182
                
175
                if (isInt32Speculation(prediction)) {
183
                if (isInt32Speculation(prediction)) {
176
                    speculateBackward(BadType, jsValue, node, isNotInt32(jsValue));
184
                    speculateBackward(BadType, jsValueValue(jsValue), node, isNotInt32(jsValue));
177
                    m_out.set(unboxInt32(jsValue), m_locals32.operand(variable->local()));
185
                    m_out.set(unboxInt32(jsValue), m_locals32.operand(variable->local()));
178
                    continue;
186
                    continue;
179
                }
187
                }
180
                
188
                
181
                if (isCellSpeculation(prediction)) {
189
                if (isCellSpeculation(prediction)) {
182
                    speculateBackward(BadType, jsValue, node, isNotCell(jsValue));
190
                    speculateBackward(BadType, jsValueValue(jsValue), node, isNotCell(jsValue));
183
                    m_out.set(jsValue, m_locals64.operand(variable->local()));
191
                    m_out.set(jsValue, m_locals64.operand(variable->local()));
184
                    continue;
192
                    continue;
185
                }
193
                }
186
                if (isBooleanSpeculation(prediction)) {
194
                if (isBooleanSpeculation(prediction)) {
187
                    speculateBackward(BadType, jsValue, node, isNotBoolean(jsValue));
195
                    speculateBackward(BadType, jsValueValue(jsValue), node, isNotBoolean(jsValue));
188
                    m_out.set(unboxBoolean(jsValue), m_localsBoolean.operand(variable->local()));
196
                    m_out.set(unboxBoolean(jsValue), m_localsBoolean.operand(variable->local()));
189
                    continue;
197
                    continue;
190
                }
198
                }
Lines 216-233 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec8
216
        // make IR dumps easier to read.
224
        // make IR dumps easier to read.
217
        m_out.appendTo(lowBlock, m_nextLowBlock);
225
        m_out.appendTo(lowBlock, m_nextLowBlock);
218
        
226
        
219
        // FIXME: We should track the OSR situation here.
227
        initializeOSRExitStateForBlock();
220
        // https://bugs.webkit.org/show_bug.cgi?id=113623
221
        
228
        
222
        m_int32Values.clear();
229
        m_int32Values.clear();
223
        m_jsValueValues.clear();
230
        m_jsValueValues.clear();
224
        m_booleanValues.clear();
231
        m_booleanValues.clear();
225
        m_storageValues.clear();
232
        m_storageValues.clear();
233
        m_timeToLive.clear();
226
        
234
        
227
        m_state.reset();
235
        m_state.reset();
228
        m_state.beginBasicBlock(m_highBlock);
236
        m_state.beginBasicBlock(m_highBlock);
229
        
237
        
230
        for (unsigned nodeIndex = 0; nodeIndex < m_highBlock->size(); ++nodeIndex)
238
        for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex)
231
            compileNode(nodeIndex);
239
            compileNode(nodeIndex);
232
    }
240
    }
233
    
241
    
Lines 240-248 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec9
240
        
248
        
241
        bool shouldExecuteEffects = m_state.startExecuting(m_node);
249
        bool shouldExecuteEffects = m_state.startExecuting(m_node);
242
        
250
        
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;
251
        m_direction = (m_node->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
247
        
252
        
248
        switch (m_node->op()) {
253
        switch (m_node->op()) {
Lines 258-263 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec10
258
        case SetLocal:
263
        case SetLocal:
259
            compileSetLocal();
264
            compileSetLocal();
260
            break;
265
            break;
266
        case MovHint:
267
            compileMovHint();
268
            break;
269
        case ZombieHint:
270
            compileZombieHint();
271
            break;
261
        case MovHintAndCheck:
272
        case MovHintAndCheck:
262
            compileMovHintAndCheck();
273
            compileMovHintAndCheck();
263
            break;
274
            break;
Lines 352-357 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec11
352
            break;
363
            break;
353
        }
364
        }
354
        
365
        
366
        DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, use);
367
        
368
        if (m_node->hasResult())
369
            m_timeToLive.add(m_node, m_node->adjustedRefCount());
370
        
355
        if (shouldExecuteEffects)
371
        if (shouldExecuteEffects)
356
            m_state.executeEffects(nodeIndex);
372
            m_state.executeEffects(nodeIndex);
357
    }
373
    }
Lines 368-375 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec12
368
    
384
    
369
    void compileGetLocal()
385
    void compileGetLocal()
370
    {
386
    {
387
        // GetLocal is one of the few nodes that may be left behind, with !shouldGenerate().
388
        if (!m_node->shouldGenerate())
389
            return;
390
        
371
        VariableAccessData* variable = m_node->variableAccessData();
391
        VariableAccessData* variable = m_node->variableAccessData();
372
        SpeculatedType prediction = variable->prediction();
392
        SpeculatedType prediction = variable->argumentAwarePrediction();
373
        AbstractValue& value = m_state.variables().operand(variable->local());
393
        AbstractValue& value = m_state.variables().operand(variable->local());
374
        
394
        
375
        if (prediction == SpecNone) {
395
        if (prediction == SpecNone) {
Lines 420-432 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec13
420
    
440
    
421
    void compileSetLocal()
441
    void compileSetLocal()
422
    {
442
    {
443
        observeMovHint(m_node);
444
        
423
        VariableAccessData* variable = m_node->variableAccessData();
445
        VariableAccessData* variable = m_node->variableAccessData();
424
        SpeculatedType prediction = variable->prediction();
446
        SpeculatedType prediction = variable->argumentAwarePrediction();
425
        bool needsFlushing = m_flushedLocalOps.contains(m_node);
447
        bool needsFlushing = m_flushedLocalOps.contains(m_node);
426
        
448
        
427
        // FIXME: Handle the MovHint for OSR.
428
        // https://bugs.webkit.org/show_bug.cgi?id=113623
429
        
430
        if (variable->shouldUnboxIfPossible()) {
449
        if (variable->shouldUnboxIfPossible()) {
431
            if (variable->shouldUseDoubleFormat()) {
450
            if (variable->shouldUseDoubleFormat()) {
432
                // FIXME: implement doubles in FTL.
451
                // FIXME: implement doubles in FTL.
Lines 438-458 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec14
438
            if (isInt32Speculation(prediction)) {
457
            if (isInt32Speculation(prediction)) {
439
                LValue value = lowInt32(m_node->child1());
458
                LValue value = lowInt32(m_node->child1());
440
                m_out.set(value, m_locals32.operand(variable->local()));
459
                m_out.set(value, m_locals32.operand(variable->local()));
441
                if (needsFlushing)
460
                if (needsFlushing) {
442
                    m_out.store32(value, payloadFor(variable->local()));
461
                    m_out.store32(value, payloadFor(variable->local()));
462
                    m_valueSources[variable->local()] = ValueSource(Int32InJSStack);
463
                }
443
                return;
464
                return;
444
            }
465
            }
445
            if (isCellSpeculation(prediction)) {
466
            if (isCellSpeculation(prediction)) {
446
                LValue value = lowCell(m_node->child1());
467
                LValue value = lowCell(m_node->child1());
447
                m_out.set(value, m_locals64.operand(variable->local()));
468
                m_out.set(value, m_locals64.operand(variable->local()));
448
                if (needsFlushing)
469
                if (needsFlushing) {
449
                    m_out.store64(value, addressFor(variable->local()));
470
                    m_out.store64(value, addressFor(variable->local()));
471
                    m_valueSources[variable->local()] = ValueSource(CellInJSStack);
472
                }
450
                return;
473
                return;
451
            }
474
            }
452
            if (isBooleanSpeculation(prediction)) {
475
            if (isBooleanSpeculation(prediction)) {
453
                m_out.set(lowBoolean(m_node->child1()), m_localsBoolean.operand(variable->local()));
476
                m_out.set(lowBoolean(m_node->child1()), m_localsBoolean.operand(variable->local()));
454
                if (needsFlushing)
477
                if (needsFlushing) {
455
                    m_out.store64(lowJSValue(m_node->child1()), addressFor(variable->local()));
478
                    m_out.store64(lowJSValue(m_node->child1()), addressFor(variable->local()));
479
                    m_valueSources[variable->local()] = ValueSource(ValueInJSStack);
480
                }
456
                return;
481
                return;
457
            }
482
            }
458
        }
483
        }
Lines 460-477 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec15
460
        LValue value = lowJSValue(m_node->child1());
485
        LValue value = lowJSValue(m_node->child1());
461
        if (variable->isCaptured()) {
486
        if (variable->isCaptured()) {
462
            m_out.store64(value, addressFor(variable->local()));
487
            m_out.store64(value, addressFor(variable->local()));
488
            m_valueSources[variable->local()] = ValueSource(ValueInJSStack);
463
            return;
489
            return;
464
        }
490
        }
465
        
491
        
466
        m_out.set(value, m_locals64.operand(variable->local()));
492
        m_out.set(value, m_locals64.operand(variable->local()));
467
        if (needsFlushing)
493
        if (needsFlushing) {
468
            m_out.store64(value, addressFor(variable->local()));
494
            m_out.store64(value, addressFor(variable->local()));
495
            m_valueSources[variable->local()] = ValueSource(ValueInJSStack);
496
        }
497
    }
498
    
499
    void compileMovHint()
500
    {
501
        observeMovHint(m_node);
502
    }
503
    
504
    void compileZombieHint()
505
    {
506
        VariableAccessData* data = m_node->variableAccessData();
507
        m_lastSetOperand = data->local();
508
        m_valueSources[data->local()] = ValueSource(SourceIsDead);
469
    }
509
    }
470
    
510
    
471
    void compileMovHintAndCheck()
511
    void compileMovHintAndCheck()
472
    {
512
    {
473
        // FIXME: Handle the MovHint for OSR.
513
        observeMovHint(m_node);
474
        // https://bugs.webkit.org/show_bug.cgi?id=113623
475
        speculate(m_node->child1());
514
        speculate(m_node->child1());
476
    }
515
    }
477
    
516
    
Lines 500-506 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec16
500
            }
539
            }
501
            
540
            
502
            LValue result = m_out.addWithOverflow32(left, right);
541
            LValue result = m_out.addWithOverflow32(left, right);
503
            speculate(Overflow, 0, 0, m_out.extractValue(result, 1));
542
            speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1));
504
            m_int32Values.add(m_node, m_out.extractValue(result, 0));
543
            m_int32Values.add(m_node, m_out.extractValue(result, 0));
505
            break;
544
            break;
506
        }
545
        }
Lines 524-530 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec17
524
            }
563
            }
525
            
564
            
526
            LValue result = m_out.subWithOverflow32(left, right);
565
            LValue result = m_out.subWithOverflow32(left, right);
527
            speculate(Overflow, 0, 0, m_out.extractValue(result, 1));
566
            speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1));
528
            m_int32Values.add(m_node, m_out.extractValue(result, 0));
567
            m_int32Values.add(m_node, m_out.extractValue(result, 0));
529
            break;
568
            break;
530
        }
569
        }
Lines 547-553 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec18
547
                result = m_out.mul(left, right);
586
                result = m_out.mul(left, right);
548
            else {
587
            else {
549
                LValue overflowResult = m_out.mulWithOverflow32(left, right);
588
                LValue overflowResult = m_out.mulWithOverflow32(left, right);
550
                speculate(Overflow, 0, 0, m_out.extractValue(overflowResult, 1));
589
                speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
551
                result = m_out.extractValue(overflowResult, 0);
590
                result = m_out.extractValue(overflowResult, 0);
552
            }
591
            }
553
            
592
            
Lines 556-563 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec19
556
                LBasicBlock continuation = m_out.newBlock();
595
                LBasicBlock continuation = m_out.newBlock();
557
                
596
                
558
                LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
597
                LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
559
                speculate(NegativeZero, 0, 0, m_out.lessThan(left, m_out.int32Zero));
598
                speculate(NegativeZero, noValue(), 0, m_out.lessThan(left, m_out.int32Zero));
560
                speculate(NegativeZero, 0, 0, m_out.lessThan(right, m_out.int32Zero));
599
                speculate(NegativeZero, noValue(), 0, m_out.lessThan(right, m_out.int32Zero));
561
                m_out.jump(continuation);
600
                m_out.jump(continuation);
562
                m_out.appendTo(continuation, lastNext);
601
                m_out.appendTo(continuation, lastNext);
563
            }
602
            }
Lines 585-591 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec20
585
                // We don't have a negate-with-overflow intrinsic. Hopefully this
624
                // We don't have a negate-with-overflow intrinsic. Hopefully this
586
                // does the trick, though.
625
                // does the trick, though.
587
                LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value);
626
                LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value);
588
                speculate(Overflow, 0, 0, m_out.extractValue(overflowResult, 1));
627
                speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1));
589
                result = m_out.extractValue(overflowResult, 0);
628
                result = m_out.extractValue(overflowResult, 0);
590
            }
629
            }
591
            
630
            
Lines 656-662 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec21
656
        
695
        
657
        LValue value = lowInt32(m_node->child1());
696
        LValue value = lowInt32(m_node->child1());
658
        speculateForward(
697
        speculateForward(
659
            Overflow, 0, 0, m_out.lessThan(value, m_out.int32Zero),
698
            Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero),
660
            FormattedValue(ValueFormatUInt32, value));
699
            FormattedValue(ValueFormatUInt32, value));
661
        m_int32Values.add(m_node, value);
700
        m_int32Values.add(m_node, value);
662
    }
701
    }
Lines 675-681 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec22
675
        
714
        
676
        if (m_node->structureSet().size() == 1) {
715
        if (m_node->structureSet().size() == 1) {
677
            speculate(
716
            speculate(
678
                exitKind, cell, 0,
717
                exitKind, jsValueValue(cell), 0,
679
                m_out.notEqual(structure, weakPointer(m_node->structureSet()[0])));
718
                m_out.notEqual(structure, weakPointer(m_node->structureSet()[0])));
680
            return;
719
            return;
681
        }
720
        }
Lines 692-698 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec23
692
        }
731
        }
693
        
732
        
694
        speculate(
733
        speculate(
695
            exitKind, cell, 0,
734
            exitKind, jsValueValue(cell), 0,
696
            m_out.notEqual(structure, weakPointer(m_node->structureSet().last())));
735
            m_out.notEqual(structure, weakPointer(m_node->structureSet().last())));
697
        
736
        
698
        m_out.appendTo(continuation, lastNext);
737
        m_out.appendTo(continuation, lastNext);
Lines 755-761 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec24
755
        case Array::Contiguous: {
794
        case Array::Contiguous: {
756
            if (m_node->arrayMode().isInBounds()) {
795
            if (m_node->arrayMode().isInBounds()) {
757
                speculate(
796
                speculate(
758
                    OutOfBounds, 0, 0,
797
                    OutOfBounds, noValue(), 0,
759
                    m_out.aboveOrEqual(
798
                    m_out.aboveOrEqual(
760
                        index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
799
                        index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
761
                
800
                
Lines 764-770 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec25
764
                        m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
803
                        m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
765
                    storage, m_out.zeroExt(index, m_out.intPtr),
804
                    storage, m_out.zeroExt(index, m_out.intPtr),
766
                    m_state.forNode(m_node->child2()).m_value));
805
                    m_state.forNode(m_node->child2()).m_value));
767
                speculate(LoadFromHole, 0, 0, m_out.isZero64(result));
806
                speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result));
768
                m_jsValueValues.add(m_node, result);
807
                m_jsValueValues.add(m_node, result);
769
                break;
808
                break;
770
            }
809
            }
Lines 865-896 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec26
865
        }
904
        }
866
    }
905
    }
867
    
906
    
868
    void speculateBackward(ExitKind, LValue, Node*, LValue failCondition)
907
    void speculateBackward(
908
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
869
    {
909
    {
870
        LBasicBlock failCase = m_out.newBlock();
910
        appendOSRExit(
871
        LBasicBlock continuation = m_out.newBlock();
911
            kind, lowValue, highValue, failCondition, BackwardSpeculation, FormattedValue());
872
        
873
        m_out.branch(failCondition, failCase, continuation);
874
        LBasicBlock lastNext = m_out.appendTo(failCase, continuation);
875
        // FIXME: Implement OSR exit.
876
        // https://bugs.webkit.org/show_bug.cgi?id=113623
877
        m_out.call(m_abortFunction);
878
        m_out.unreachable();
879
        m_out.appendTo(continuation, lastNext);
880
    }
912
    }
881
    
913
    
882
    void speculateForward(ExitKind kind, LValue lowValue, Node* highValue, LValue failCondition, const FormattedValue&)
914
    void speculateForward(
915
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition,
916
        const FormattedValue& recovery)
883
    {
917
    {
884
        speculateBackward(kind, lowValue, highValue, failCondition);
918
        appendOSRExit(
885
        // FIXME: Implement rewiring of OSR exit to forward.
919
            kind, lowValue, highValue, failCondition, ForwardSpeculation, recovery);
886
        // https://bugs.webkit.org/show_bug.cgi?id=113623
887
    }
920
    }
888
    
921
    
889
    void speculate(ExitKind kind, LValue lowValue, Node* highValue, LValue failCondition)
922
    void speculate(
923
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
890
    {
924
    {
891
        speculateBackward(kind, lowValue, highValue, failCondition);
925
        appendOSRExit(
892
        // FIXME: Implement rewiring the OSR exit to forward, if m_direction == ForwardDirection.
926
            kind, lowValue, highValue, failCondition, m_direction, FormattedValue());
893
        // https://bugs.webkit.org/show_bug.cgi?id=113623
894
    }
927
    }
895
    
928
    
896
    void terminate(ExitKind kind)
929
    void terminate(ExitKind kind)
Lines 898-924 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec27
898
        speculate(kind, 0, 0, m_out.booleanTrue);
931
        speculate(kind, 0, 0, m_out.booleanTrue);
899
    }
932
    }
900
    
933
    
901
    void backwardTypeCheck(LValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, LValue failCondition)
934
    void backwardTypeCheck(
935
        FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
936
        LValue failCondition)
902
    {
937
    {
903
        if (!m_state.needsTypeCheck(highValue, typesPassedThrough))
938
        appendTypeCheck(
904
            return;
939
            lowValue, highValue, typesPassedThrough, failCondition, BackwardSpeculation,
905
        ASSERT(mayHaveTypeCheck(highValue.useKind()));
940
            FormattedValue());
906
        speculateBackward(BadType, lowValue, highValue.node(), failCondition);
907
        m_state.forNode(highValue).filter(typesPassedThrough);
908
    }
941
    }
909
    
942
    
910
    void forwardTypeCheck(LValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, LValue failCondition)
943
    void forwardTypeCheck(
944
        FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
945
        LValue failCondition)
911
    {
946
    {
912
        backwardTypeCheck(lowValue, highValue, typesPassedThrough, failCondition);
947
        appendTypeCheck(
913
        // FIXME: Implement rewiring of OSR exit to forward.
948
            lowValue, highValue, typesPassedThrough, failCondition, ForwardSpeculation,
914
        // https://bugs.webkit.org/show_bug.cgi?id=113623
949
            FormattedValue());
915
    }
950
    }
916
    
951
    
917
    void typeCheck(LValue lowValue, Edge highValue, SpeculatedType typesPassedThrough, LValue failCondition)
952
    void typeCheck(
953
        FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
954
        LValue failCondition)
918
    {
955
    {
919
        backwardTypeCheck(lowValue, highValue, typesPassedThrough, failCondition);
956
        appendTypeCheck(
920
        // FIXME: Implement rewiring of OSR exit to forward, if m_direction == ForwardDirection.
957
            lowValue, highValue, typesPassedThrough, failCondition, m_direction,
921
        // https://bugs.webkit.org/show_bug.cgi?id=113623
958
            FormattedValue());
959
    }
960
    
961
    void appendTypeCheck(
962
        LValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
963
        LValue failCondition, SpeculationDirection direction, FormattedValue recovery)
964
    {
965
        if (!m_state.needsTypeCheck(highValue, typesPassedThrough))
966
            return;
967
        ASSERT(mayHaveTypeCheck(highValue.useKind()));
968
        appendOSRExit(BadType, lowValue, highValue.node(), failCondition, direction, recovery);
969
        m_state.forNode(highValue).filter(typesPassedThrough);
922
    }
970
    }
923
    
971
    
924
    LValue lowInt32(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
972
    LValue lowInt32(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
Lines 929-935 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec28
929
            return result;
977
            return result;
930
        
978
        
931
        if (LValue boxedResult = m_jsValueValues.get(edge.node())) {
979
        if (LValue boxedResult = m_jsValueValues.get(edge.node())) {
932
            FTL_TYPE_CHECK(boxedResult, edge, SpecInt32, isNotInt32(boxedResult));
980
            FTL_TYPE_CHECK(
981
                jsValueValue(boxedResult), edge, SpecInt32, isNotInt32(boxedResult));
933
            LValue result = unboxInt32(boxedResult);
982
            LValue result = unboxInt32(boxedResult);
934
            m_int32Values.add(edge.node(), result);
983
            m_int32Values.add(edge.node(), result);
935
            return result;
984
            return result;
Lines 945-951 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec29
945
        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
994
        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
946
        
995
        
947
        if (LValue uncheckedResult = m_jsValueValues.get(edge.node())) {
996
        if (LValue uncheckedResult = m_jsValueValues.get(edge.node())) {
948
            FTL_TYPE_CHECK(uncheckedResult, edge, SpecCell, isNotCell(uncheckedResult));
997
            FTL_TYPE_CHECK(
998
                jsValueValue(uncheckedResult), edge, SpecCell, isNotCell(uncheckedResult));
949
            return uncheckedResult;
999
            return uncheckedResult;
950
        }
1000
        }
951
        
1001
        
Lines 971-977 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec30
971
            return result;
1021
            return result;
972
        
1022
        
973
        if (LValue unboxedResult = m_jsValueValues.get(edge.node())) {
1023
        if (LValue unboxedResult = m_jsValueValues.get(edge.node())) {
974
            FTL_TYPE_CHECK(unboxedResult, edge, SpecBoolean, isNotBoolean(unboxedResult));
1024
            FTL_TYPE_CHECK(
1025
                jsValueValue(unboxedResult), edge, SpecBoolean, isNotBoolean(unboxedResult));
975
            LValue result = unboxBoolean(unboxedResult);
1026
            LValue result = unboxBoolean(unboxedResult);
976
            m_booleanValues.add(edge.node(), result);
1027
            m_booleanValues.add(edge.node(), result);
977
            return result;
1028
            return result;
Lines 1094-1100 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec31
1094
    void speculateObject(Edge edge, LValue cell)
1145
    void speculateObject(Edge edge, LValue cell)
1095
    {
1146
    {
1096
        FTL_TYPE_CHECK(
1147
        FTL_TYPE_CHECK(
1097
            cell, edge, SpecObject,
1148
            jsValueValue(cell), edge, SpecObject,
1098
            m_out.equal(
1149
            m_out.equal(
1099
                m_out.loadPtr(cell, m_heaps.JSCell_structure),
1150
                m_out.loadPtr(cell, m_heaps.JSCell_structure),
1100
                m_out.constIntPtr(globalData().stringStructure.get())));
1151
                m_out.constIntPtr(globalData().stringStructure.get())));
Lines 1105-1110 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec32
1105
        speculateObject(edge, lowCell(edge));
1156
        speculateObject(edge, lowCell(edge));
1106
    }
1157
    }
1107
    
1158
    
1159
    bool isLive(Node* node)
1160
    {
1161
        HashMap<Node*, unsigned>::iterator iter = m_timeToLive->find(edge.node());
1162
        ASSERT(iter != m_timeToLive->end());
1163
        return !!iter->value;
1164
    }
1165
    
1166
    void use(Edge edge)
1167
    {
1168
        HashMap<Node*, unsigned>::iterator iter = m_timeToLive->find(edge.node());
1169
        ASSERT(iter != m_timeToLive->end());
1170
        ASSERT(iter->value);
1171
        iter->value--;
1172
    }
1173
    
1174
    // Wrapper used only for DFG_NODE_DO_TO_CHILDREN
1175
    void use(Node*, Edge edge)
1176
    {
1177
        use(edge);
1178
    }
1179
    
1180
    void initializeOSRExitStateForBlock()
1181
    {
1182
        for (unsigned i = m_valueSources.size(); i--;) {
1183
            Node* node = m_highBlock->variablesAtHead[i];
1184
            if (!node) {
1185
                m_valueSources[i] = ValueSource(SourceIsDead);
1186
                continue;
1187
            }
1188
            
1189
            VariableAccessData* variable = node->variableAccessData();
1190
            SpeculatedType prediction = variable->argumentAwarePrediction();
1191
            
1192
            if (variable->isArgumentsAlias()) {
1193
                m_valueSources[i] = ValueSource(ArgumentsSource);
1194
                continue;
1195
            }
1196
            
1197
            if (!node->shouldGenerate()) {
1198
                m_valueSources[i] = ValueSource(SourceIsDead);
1199
                continue;
1200
            }
1201
            
1202
            if (m_flushedLocalOps.contains(node)) {
1203
                // This value will have been flushed to the JSStack in some form or
1204
                // another.
1205
                
1206
                if (variable->shouldUnboxIfPossible()) {
1207
                    if (variable->shouldUseDoubleFormat()) {
1208
                        m_valueSources[i] = ValueSource(DoubleInJSStack);
1209
                        continue;
1210
                    }
1211
                    
1212
                    if (isInt32Speculation(prediction)) {
1213
                        m_valueSources[i] = ValueSource(Int32InJSStack);
1214
                        continue;
1215
                    }
1216
                }
1217
                
1218
                m_valueSources[i] = ValueSource(ValueInJSStack);
1219
                continue;
1220
            }
1221
            
1222
            if (variable->shouldUnboxIfPossible()) {
1223
                if (variable->shouldUseDoubleFormat()) {
1224
                    m_valueSources[i] = ValueSource(ValueInLocals);
1225
                    continue;
1226
                }
1227
                
1228
                if (isInt32Speculation(prediction)) {
1229
                    m_valueSources[i] = ValueSource(Int32InLocals);
1230
                    continue;
1231
                }
1232
                
1233
                if (isBooleanSpeculation(prediction)) {
1234
                    m_valueSources[i] = ValueSource(BooleanInLocals);
1235
                    continue;
1236
                }
1237
            }
1238
            
1239
            m_valueSources[i] = ValueSource(ValueInLocals);
1240
        }
1241
    }
1242
    
1243
    void appendOSRExit(
1244
        ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition,
1245
        SpeculationDirection direction, FormattedValue recovery)
1246
    {
1247
        m_ftlState.jitCode->osrExit.append(
1248
            OSRExit(
1249
                kind, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
1250
                m_node->codeOrigin, m_lastSetOperand, m_valueSources.numberOfArguments(),
1251
                m_valueSources.numberOfLocals()));
1252
        m_ftlState.osrExit.append(OSRExitCompilationInfo());
1253
        
1254
        OSRExit& exit = m_ftlState.jitCode->osrExit.last();
1255
        OSRExitCompilationInfo& info = m_ftlState.osrExit.last();
1256
1257
        LBasicBlock failCase = m_out.newBlock();
1258
        LBasicBlock continuation = m_out.newBlock();
1259
        
1260
        m_out.branch(failCondition, failCase, continuation);
1261
        
1262
        m_out.appendTo(m_prologue);
1263
        info.m_thunkAddress = buildAlloca(m_out.m_builder, m_out.intPtr);
1264
        
1265
        LBasicBlock lastNext = m_out.appendTo(failCase, continuation);
1266
        
1267
        ExitArgumentList arguments;
1268
        arguments.append(m_callFrame);
1269
        if (lowValue)
1270
            arguments.append(arguments.value());
1271
        
1272
        for (unsigned i = 0; i < exit.m_values.size(); ++i) {
1273
            ValueSource source = m_valueSources[i];
1274
            
1275
            switch (source.kind()) {
1276
            case ValueInJSStack:
1277
                exit.m_values[i] = ExitValue::inJSStack();
1278
                break;
1279
            case Int32InJSStack:
1280
                exit.m_values[i] = ExitValue::inJSStackAsIn32();
1281
                break;
1282
            case DoubleInJSStack:
1283
                exit.m_values[i] = ExitValue::inJSStackAsDouble();
1284
                break;
1285
            case ValueInLocals:
1286
                addExitArgument(
1287
                    exit, arguments, i, ValueFormatJSValue, m_out.get(m_locals64[i]));
1288
                break;
1289
            case Int32InLocals:
1290
                addExitArgument(
1291
                    exit, arguments, i, ValueFormatInt32, m_out.get(m_locals32[i]));
1292
                break;
1293
            case BooleanInLocals:
1294
                addExitArgument(
1295
                    exit, arguments, i, ValueFormatBoolean, m_out.get(m_localsBoolean[i]));
1296
                break;
1297
            case DoubleInLocals:
1298
                // FIXME: implement doubles in FTL.
1299
                // https://bugs.webkit.org/show_bug.cgi?id=113624
1300
                RELEASE_ASSERT_NOT_REACHED();
1301
                break;
1302
            case ArgumentsSource:
1303
                // FIXME: implement PhantomArguments.
1304
                // https://bugs.webkit.org/show_bug.cgi?id=113986
1305
                RELEASE_ASSERT_NOT_REACHED();
1306
                break;
1307
            case SourceIsDead:
1308
                exit.m_values[i] = ExitValue::dead();
1309
                break;
1310
            case HaveNode:
1311
                addExitArgumentForNode(exit, arguments, i, source.node());
1312
                break;
1313
            default:
1314
                RELEASE_ASSERT_NOT_REACHED();
1315
                break;
1316
            }
1317
        }
1318
        
1319
        if (direction = ForwardSpeculation)
1320
            exit.convertToForward(m_highBlock, m_node, m_nodeIndex, recovery, arguments);
1321
        
1322
        // So, the really lame thing here is that we have to build an LLVM function type.
1323
        // Booo.
1324
        Vector<LType, 16> argumentTypes;
1325
        for (unsigned i = 0; i < arguments.size(); ++i)
1326
            argumentTypes.append(typeOf(arguments[i]));
1327
        
1328
        m_out.call(
1329
            m_out.intToPtr(
1330
                m_out.get(info.m_thunkAddress),
1331
                pointerType(functionType(m_out.voidType, argumentTypes))),
1332
            arguments);
1333
        
1334
        m_out.appendTo(continuation, lastNext);
1335
    }
1336
    
1337
    void addExitArgumentForNode(
1338
        OSRExit& exit, ExitArgumentList& arguments, unsigned index, Node* node)
1339
    {
1340
        ASSERT(node->shouldGenerate());
1341
        ASSERT(node->hasResult());
1342
1343
        if (tryToSetConstantExitArument(exit, arguments, index, node))
1344
            return;
1345
        
1346
        if (!isLive(node)) {
1347
            bool found = false;
1348
            
1349
            if (needsOSRBackwardRewiring(node->op())) {
1350
                node = node->child1().node();
1351
                if (tryToSetConstantExitArgument(exit, arguments, index, node))
1352
                    return;
1353
                if (isLive(node))
1354
                    found = true;
1355
            }
1356
            
1357
            if (!found) {
1358
                Node* int32ToDouble = 0;
1359
                Node* valueToInt32 = 0;
1360
                Node* uint32ToNumber = 0;
1361
                Node* doubleAsInt32 = 0;
1362
                
1363
                HashMap<Node*, unsigned>::iterator iter = m_timeToLive.begin();
1364
                HashMap<Node*, unsigned>::iterator end = m_timeToLive.end();
1365
                for (; iter != end; ++iter) {
1366
                    if (!iter->value)
1367
                        continue;
1368
                    Node* candidate = iter->key;
1369
                    if (!candidate->child1())
1370
                        continue;
1371
                    if (candidate->child1() != node)
1372
                        continue;
1373
                    switch (candidate->op()) {
1374
                    case Int32ToDouble:
1375
                    case ForwardInt32ToDouble:
1376
                        int32ToDouble = candidate;
1377
                        break;
1378
                    case ValueToInt32:
1379
                        valueToInt32 = candidate;
1380
                        break;
1381
                    case UInt32ToNumber:
1382
                        uint32ToNumber = candidate;
1383
                        break;
1384
                    case DoubleAsInt32:
1385
                        uint32ToNumber = candidate;
1386
                        break;
1387
                    default:
1388
                        ASSERT(!needsOSRForwardRewiring(candidate->op()));
1389
                        break;
1390
                    }
1391
                }
1392
                
1393
                if (doubleAsInt32)
1394
                    node = doubleAsIn32;
1395
                else if (int32ToDouble)
1396
                    node = int32ToDouble;
1397
                else if (valueToInt32)
1398
                    node = valueToInt32;
1399
                else if (uint32ToNumber)
1400
                    node = uint32ToNumber;
1401
                
1402
                if (isLive(node))
1403
                    found = true;
1404
            }
1405
            
1406
            if (!found) {
1407
                exit.m_values[index] = ExitValue::dead();
1408
                return;
1409
            }
1410
        }
1411
        
1412
        ASSERT(isLive(node));
1413
        
1414
        if (LValue result = m_int32Values.get(node)) {
1415
            addExitArgument(exit, arguments, index, ValueFormatInt32, result);
1416
            return;
1417
        }
1418
        
1419
        if (LValue result = m_booleanValues.get(node)) {
1420
            addExitArgument(exit, arguments, index, ValueFormatBoolean, result);
1421
            return;
1422
        }
1423
        
1424
        if (LValue result = m_jsValueValues.get(node)) {
1425
            addExitArgument(exit, arguments, index, ValueFormatJSValue, result);
1426
            return;
1427
        }
1428
        
1429
        // FIXME: Implement doubles in the FTL.
1430
        // https://bugs.webkit.org/show_bug.cgi?id=113624
1431
        RELEASE_ASSERT_NOT_REACHED();
1432
    }
1433
    
1434
    void tryToSetConstantExitArgument(
1435
        OSRExit& exit, ExitArgumentList& arguments, unsigned index, Node* node)
1436
    {
1437
        if (!node)
1438
            return false;
1439
        
1440
        switch (node->op()) {
1441
        case JSConstant:
1442
        case WeakJSConstant:
1443
            exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
1444
            return true;
1445
        case PhantomArguments:
1446
            // FIXME: implement PhantomArguments.
1447
            // https://bugs.webkit.org/show_bug.cgi?id=113986
1448
            RELEASE_ASSERT_NOT_REACHED();
1449
            return true;
1450
        default:
1451
            return false;
1452
        }
1453
    }
1454
    
1455
    void addExitArgument(
1456
        OSRExit& exit, ExitArgumentList& arguments, unsigned index, ValueFormat format,
1457
        LValue value)
1458
    {
1459
        exit.m_values[i] = ExitValue::exitArgument(ExitArgument(format, arguments.size()));
1460
        arguments.append(value);
1461
    }
1462
    
1463
    void linkOSRExitsAndCompleteInitializationBlock()
1464
    {
1465
        MacroAssemblerCodeRef osrExitThunk =
1466
            globalData().getCTIStub(osrExitGenerationThunkGenerator);
1467
        CodeLocationLabel target = CodeLocationLabel(osrExitThunk.code());
1468
        
1469
        m_out.appendTo(m_initialization);
1470
        
1471
        LinkBuffer linkBuffer(
1472
            &globalData(), &m_exitThunkGenerator, m_ftlState.graph.m_codeBlock,
1473
            JITCompilationMustSucceed);
1474
        
1475
        ASSERT(m_ftlState.osrExit.size() == m_ftlState.jitCode->osrExit.size());
1476
        
1477
        for (unsigned i = 0; i < m_ftlState.osrExit.size(); ++i) {
1478
            OSRExitCompilationInfo& info = m_ftlState.osrExit[i];
1479
            OSRExit& exit = m_ftlState.jitCode->osrExit[i];
1480
            
1481
            linkBuffer.link(info.m_thunkJump, target);
1482
            
1483
            m_out.set(
1484
                m_out.constIntPtr(
1485
                    linkBuffer.locationOf(info.m_thunkLabel).executableAddress()),
1486
                info.m_thunkAddress);
1487
            
1488
            exit.m_patchableCodeOffset = linkBuffer.offsetOf(exit.m_thunkJump);
1489
        }
1490
        
1491
        state.jitCode->initializeExitThunks(
1492
            FINALIZE_DFG_CODE(
1493
                linkBuffer,
1494
                ("FTL exit thunks for %s", toCString(CodeBlockWithJITType(state.graph.m_codeBlock,JITCode::FTLJIT)).data())));
1495
1496
        m_out.jump(m_blocks.get(m_graph.m_blocks[0].get()));
1497
    }
1498
    
1499
    void observeMovHint(Node* node)
1500
    {
1501
        ASSERT(node->containsMovHint());
1502
        ASSERT(node->op() != ZombieHint);
1503
        
1504
        int operand = node->local();
1505
        
1506
        m_lastSetOperand = operand;
1507
        m_valueSources[operand] = ValueSource(node->child1().node());
1508
    }
1509
    
1108
    void addWeakReference(JSCell* target)
1510
    void addWeakReference(JSCell* target)
1109
    {
1511
    {
1110
        m_ftlState.jitCode->common.weakReferences.append(
1512
        m_ftlState.jitCode->common.weakReferences.append(
Lines 1151-1162 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec33
1151
    Output m_out;
1553
    Output m_out;
1152
    
1554
    
1153
    LBasicBlock m_prologue;
1555
    LBasicBlock m_prologue;
1556
    LBasicBlock m_initialization;
1154
    HashMap<BasicBlock*, LBasicBlock> m_blocks;
1557
    HashMap<BasicBlock*, LBasicBlock> m_blocks;
1155
    
1558
    
1156
    LValue m_callFrame;
1559
    LValue m_callFrame;
1157
    LValue m_tagTypeNumber;
1560
    LValue m_tagTypeNumber;
1158
    LValue m_tagMask;
1561
    LValue m_tagMask;
1159
    LValue m_abortFunction;
1160
    
1562
    
1161
    HashSet<Node*> m_flushedLocalOps;
1563
    HashSet<Node*> m_flushedLocalOps;
1162
    Vector<Node*> m_flushedLocalOpWorklist;
1564
    Vector<Node*> m_flushedLocalOpWorklist;
Lines 1165-1179 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec34
1165
    HashMap<Node*, LValue> m_jsValueValues;
1567
    HashMap<Node*, LValue> m_jsValueValues;
1166
    HashMap<Node*, LValue> m_booleanValues;
1568
    HashMap<Node*, LValue> m_booleanValues;
1167
    HashMap<Node*, LValue> m_storageValues;
1569
    HashMap<Node*, LValue> m_storageValues;
1570
    HashMap<Node*, unsigned> m_timeToLive;
1168
    
1571
    
1169
    Operands<LValue> m_localsBoolean;
1572
    Operands<LValue> m_localsBoolean;
1170
    Operands<LValue> m_locals32;
1573
    Operands<LValue> m_locals32;
1171
    Operands<LValue> m_locals64;
1574
    Operands<LValue> m_locals64;
1172
    
1575
    
1576
    Operands<ValueSource> m_valueSources;
1577
    int m_lastSetOperand;
1578
    ExitThunkGenerator m_exitThunkGenerator;
1579
    
1173
    AbstractState m_state;
1580
    AbstractState m_state;
1174
    BasicBlock* m_highBlock;
1581
    BasicBlock* m_highBlock;
1175
    BasicBlock* m_nextHighBlock;
1582
    BasicBlock* m_nextHighBlock;
1176
    LBasicBlock m_nextLowBlock;
1583
    LBasicBlock m_nextLowBlock;
1584
    unsigned m_nodeIndex;
1177
    Node* m_node;
1585
    Node* m_node;
1178
    SpeculationDirection m_direction;
1586
    SpeculationDirection m_direction;
1179
};
1587
};
- Source/JavaScriptCore/ftl/FTLOSRExit.cpp +92 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,
36
    int lastSetOperand, unsigned numberOfArguments, unsigned numberOfLocals)
37
    : OSRExitBase(exitKind, codeOrigin)
38
    , m_profileValueFormat(profileValueFormat)
39
    , m_valueProfile(valueProfile)
40
    , m_patchableCodeOffset(0)
41
    , m_lastSetOperand(lastSetOperand)
42
    , m_values(numberOfArguments, numberOfLocals)
43
{
44
}
45
46
CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* ftlCodeBlock) const
47
{
48
    return CodeLocationJump(
49
        reinterpret_cast<char*>(
50
            ftlCodeBlock->getJITCode()->ftl()->exitThunks().dataLocation()) +
51
        m_patchableCodeOffset);
52
}
53
54
void OSRExit::convertToForward(
55
    DFG::BasicBlock* block, DFG::Node* currentNode, unsigned nodeIndex,
56
    const FormattedValue &value, ExitArgumentList& arguments)
57
{
58
    Node* node;
59
    Node* lastMovHint;
60
    doSearchForForwardConversion(block, currentNode, nodeIndex, !!valueRecovery);
61
62
    ASSERT(node->codeOrigin != currentNode->codeOrigin);
63
    
64
    m_codeOrigin = node->codeOrigin;
65
    
66
    if (!value)
67
        return;
68
    
69
    int overriddenOperand = lastMovHint->local();
70
    m_lastSetOperand = overriddenOperand;
71
    
72
    // Is the value for this operand being passed as an argument to the exit, or is
73
    // it something else? If it's an argument already, then replace that argument;
74
    // otherwise add another argument.
75
    if (m_values[overriddenOperand].isArgument()) {
76
        ExitArgument argument = m_values[overriddenOperand].exitArgument();
77
        arguments[exitArgument.argument()] = value.value();
78
        m_values[overriddenOperand] = ExitValue::exitArgument(
79
            exitArgument.withFormat(value.format()));
80
        return;
81
    }
82
    
83
    unsigned argument = arguments.size();
84
    arguments.append(value.value());
85
    m_values[m_lastSetOperand] = ExitValue::exitArgument(
86
        ExitArgument(value.format(), argument));
87
}
88
89
} } // namespace JSC::FTL
90
91
#endif // ENABLE(FTL_JIT)
92
- Source/JavaScriptCore/ftl/FTLOSRExit.h +178 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 "FTLExitArgumentList.h"
38
#include "FTLExitValue.h"
39
#include "MethodOfGettingAValueProfile.h"
40
#include "Operands.h"
41
#include "ValueProfile.h"
42
43
namespace JSC { namespace FTL {
44
45
// Tracks one OSR exit site within the FTL JIT. OSR exit in FTL works by deconstructing
46
// the crazy that is OSR down to simple SSA CFG primitives that any compiler backend
47
// (including of course LLVM) can grok and do meaningful things to. Except for
48
// watchpoint-based exits, which haven't yet been implemented (see webkit.org/b/113647),
49
// an exit is just a conditional branch in the emitted code where one destination is the
50
// continuation and the other is a basic block that performs a no-return tail-call to an
51
// exit thunk. This thunk takes as its arguments the live non-constant
52
// not-already-accounted-for bytecode state. To appreciate how this works consider the
53
// following JavaScript program, and its lowering down to LLVM IR including the relevant
54
// exits:
55
//
56
// function foo(o) {
57
//     var a = o.a; // predicted int
58
//     var b = o.b;
59
//     var c = o.c; // NB this is dead
60
//     a = a | 5; // our example OSR exit: need to check if a is an int
61
//     return a + b;
62
// }
63
//
64
// Just consider the "a | 5". In the DFG IR, this looks like:
65
//
66
// BitOr(Check:Int32:@a, Int32:5)
67
//
68
// Where @a is the node for the GetLocal node that gets the value of the 'a' variable.
69
// Conceptually, this node can be further broken down to the following (note that this
70
// particular lowering never actually happens - we skip this step and go straight to
71
// LLVM IR - but it's still useful to see this):
72
//
73
// exitIf(@a is not int32);
74
// continuation;
75
//
76
// Where 'exitIf()' is a function that will exit if the argument is true, and
77
// 'continuation' is the stuff that we will do after the exitIf() check. (Note that
78
// FTL refers to 'exitIf()' as 'speculate()', which is in line with DFG terminology.)
79
// This then gets broken down to the following LLVM IR, assuming that %0 is the LLVM
80
// value corresponding to variable 'a', and %1 is the LLVM value for variable 'b':
81
//
82
//   %2 = ... // the predictate corresponding to '@a is not int32'
83
//   br i1 %2, label %3, label %4
84
// ; <label>:3
85
//   call void exitThunk1(%0, %1) // pass 'a' and 'b', since they're both live-in-bytecode
86
//   unreachable
87
// ; <label>:4
88
//   ... // code for the continuation
89
//
90
// Where 'exitThunk1' is the IR to get the exit thunk for *this* OSR exit. Each OSR
91
// exit will appear to LLVM to have a distinct exit thunk.
92
//
93
// Note that this didn't have to pass '5', 'o', or 'c' to the exit thunk. 5 is a
94
// constant and the DFG already knows that, and can already tell the OSR exit machinery
95
// what that contant is and which bytecode variables (if any) it needs to be dropped
96
// into. This is conveyed to the exit statically, via the OSRExit data structure below.
97
// See the code for ExitValue for details. 'o' is an argument, and arguments are always
98
// "flushed" - if you never assign them then their values are still in the argument
99
// stack slots, and if you do assign them then we eagerly store them into those slots.
100
// 'c' is dead in bytecode, and the DFG knows this; we statically tell the exit thunk
101
// that it's dead and don't have to pass anything. The exit thunk will "initialize" its
102
// value to Undefined.
103
//
104
// This approach to OSR exit has a number of virtues:
105
//
106
// - It is an entirely unsurprising representation for a compiler that already groks
107
//   CFG-like IRs for C-like languages. All existing analyses and transformations just
108
//   work.
109
//
110
// - It lends itself naturally to modern approaches to code motion. For example, you
111
//   could sink operations from above the exit to below it, if you just duplicate the
112
//   operation into the OSR exit block. This is both legal and desirable. It works
113
//   because the backend sees the OSR exit block as being no different than any other,
114
//   and LLVM already supports sinking if it sees that a value is only partially used.
115
//   Hence there exists a value that dominates the exit but is only used by the exit
116
//   thunk and not by the continuation, sinking ought to kick in for that value.
117
//   Hoisting operations from below it to above it is also possible, for similar
118
//   reasons.
119
//
120
// - The no-return tail-call to the OSR exit thunk can be subjected to specialized
121
//   code-size reduction optimizations, though this is optional. For example, instead
122
//   of actually emitting a call along with all that goes with it (like placing the
123
//   arguments into argument position), the backend could choose to simply inform us
124
//   where it had placed the arguments and expect the callee (i.e. the exit thunk) to
125
//   figure it out from there. It could also tell us what we need to do to pop stack,
126
//   although again, it doesn't have to; it could just emit that code normally. Though
127
//   we don't support this yet, we could; the only thing that would change on our end
128
//   is that we'd need feedback from the backend about the location of the arguments
129
//   and a description of the things that need to be done to pop stack. This would
130
//   involve switching the m_values array to use something more akin to ValueRecovery
131
//   rather than the current ExitValue, albeit possibly with some hacks to better
132
//   understand the kinds of places where the LLVM backend would put values.
133
//
134
// - It could be extended to allow the backend to do its own exit hoisting, by using
135
//   intrinsics (or meta-data, or something) to inform the backend that it's safe to
136
//   make the predicate passed to 'exitIf()' more truthy.
137
//
138
// - It could be extended to support watchpoints (see webkit.org/b/113647) by making
139
//   the predicate passed to 'exitIf()' be an intrinsic that the backend knows to be
140
//   true at compile-time. The backend could then turn the conditional branch into a
141
//   replaceable jump, much like the DFG does.
142
143
struct OSRExit : public OSRExitBase {
144
    OSRExit(
145
        ExitKind, ValueFormat profileValueFormat, MethodOfGettingAValueProfile,
146
        CodeOrigin, int lastSetOperand, unsigned numberOfArguments,
147
        unsigned numberOfLocals);
148
    
149
    MacroAssemblerCodeRef m_code;
150
    
151
    // The first argument to the exit call may be a value we wish to profile.
152
    // If that's the case, the format will be not Invalid and we'll have a
153
    // method of getting a value profile. Note that all of the ExitArgument's
154
    // are already aware of this possible off-by-one, so there is no need to
155
    // correct them.
156
    ValueFormat m_profileValueFormat;
157
    MethodOfGettingAValueProfile m_valueProfile;
158
    
159
    // Offset within the exit stubs of the stub for this exit.
160
    unsigned m_patchableCodeOffset;
161
    
162
    int m_lastSetOperand;
163
    
164
    Operands<ExitValue> m_values;
165
    
166
    CodeLocationJump codeLocationForRepatch(CodeBlock* ftlCodeBlock) const;
167
    
168
    void convertToForward(
169
        DFG::BasicBlock*, DFG::Node* currentNode, unsigned nodeIndex,
170
        const FormattedValue&, ExitArgumentList& arguments);
171
};
172
173
} } // namespace JSC::FTL
174
175
#endif // ENABLE(FTL_JIT)
176
177
#endif // FTLOSRExit_h
178
- Source/JavaScriptCore/ftl/FTLOSRExitCompilationInfo.h +54 lines
Line 0 Source/JavaScriptCore/ftl/FTLOSRExitCompilationInfo.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 FTLOSRExitCompilationInfo_h
27
#define FTLOSRExitCompilationInfo_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "FTLAbbreviations.h"
34
#include "MacroAssembler.h"
35
36
namespace JSC { namespace FTL {
37
38
struct OSRExitCompilationInfo {
39
    OSRExitCompilationInfo()
40
        : m_thunkAddress(0)
41
    {
42
    }
43
    
44
    MacroAssembler::Label m_thunkLabel;
45
    MacroAssembler::PatchableJump m_thunkJump;
46
    LValue m_thunkAddress;
47
};
48
49
} } // namespace JSC::FTL
50
51
#endif // ENABLE(FTL_JIT)
52
53
#endif // FTLOSRExitCompilationInfo_h
54
- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp +176 lines
Line 0 Source/JavaScriptCore/ftl/FTLOSRExitCompiler.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 "FTLOSRExitCompiler.h"
28
29
#if ENABLE(FTL_JIT)
30
31
#include "DFGOSRExitCompilerCommon.h"
32
#include "DFGOSRExitPreparation.h"
33
#include "FTLCArgumentGetter.h"
34
35
namespace JSC { namespace FTL {
36
37
using namespace DFG;
38
39
static compileStub(
40
    unsigned exitID, OSRExit& exit, JSGlobalData* globalData, CodeBlock* codeBlock)
41
{
42
    CCallHelpers jit(globalData, codeBlock);
43
    
44
    // This is actually fairly easy, even though it is horribly gross. We know that
45
    // LLVM would have passes us all of the state via arguments. We know how to get
46
    // the arguments. And, we know how to pop stack back to the JIT stack frame, sort
47
    // of: we know that it's two frames beneath us. This is terrible and I feel
48
    // ashamed of it, but it will work for now.
49
    
50
    CArgumentGetter arguments(jit);
51
    
52
    // First recover our call frame and tag thingies.
53
    arguments.loadNextPtr(GPRInfo::callFrameRegister);
54
    jit.move(MacroAssembler::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);
55
    jit.move(MacroAssembler::TrustedImm64(TagMask), GPRInfo::tagMaskRegister);
56
    
57
    // Do some value profiling.
58
    if (exit.m_profileValueFormat != InvalidValueFormat) {
59
        arguments.loadNextAndBox(exit.m_profileValueFormat, GPRInfo::nonArgGPR0);
60
        
61
        if (exit.m_kind == BadCache || exit.m_kind == BadIndexingType) {
62
            CodeOrigin codeOrigin = exit.m_codeOriginForExitProfile;
63
            if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {
64
                jit.loadPtr(MacroAssembler::Address(GPRInfo::nonArgGPR0, JSCell::structureOffset()), GPRInfo::nonArgGPR1);
65
                jit.storePtr(GPRInfo::nonArgGPR1, arrayProfile->addressOfLastSeenStructure());
66
                jit.load8(MacroAssembler::Address(GPRInfo::nonArgGPR1, Structure::indexingTypeOffset()), GPRInfo::nonArgGPR1);
67
                jit.move(MacroAssembler::TrustedImm32(1), GPRInfo::nonArgGPR2);
68
                jit.lshift32(GPRInfo::nonArgGPR1, GPRInfo::nonArgGPR2);
69
                jit.or32(GPRInfo::nonArgGPR2, MacroAssembler::AbsoluteAddress(arrayProfile->addressOfArrayModes()));
70
            }
71
        }
72
        
73
        if (!!exit.m_valueProfile)
74
            jit.store64(GPRInfo::nonArgGPR0, exit.m_valueProfile.getSpecFailBucket(0));
75
    }
76
    
77
    // Start by dumping all argument exit values to the stack.
78
    
79
    Vector<ExitArgumentForOperand, 16> sortedArguments;
80
    for (unsigned i = exit.m_values.size(); i--;) {
81
        ExitValue value = exit.m_values[i];
82
        int operand = exit.m_values.operandForIndex(i);
83
        
84
        if (!value.isArgument())
85
            continue;
86
        
87
        sortedArguments.append(ExitArgumentForOperand(value.exitArgument(), operand));
88
    }
89
    std::sort(sortedArguments.begin(), sortedArguments.end(), lesserArgumentIndex);
90
    
91
    for (unsigned i = 0; i < sortedArguments.size(); ++i) {
92
        ExitArgumentForOperand argument = sortedArguments[i];
93
        
94
        arguments.loadNextAndBox(argument.exitArgument().format(), GPRInfo::nonArgGPR0);
95
        jit.store64(GPRInfo::nonArgGPR0, MacroAssembler::Address(GPRInfo::callFrameRegister, argument.operand() * sizeof(EncodedJSValue)));
96
    }
97
    
98
    // Box anything that is already on the stack, or that is a constant.
99
    
100
    for (unsigned i = exit.m_values.size(); i--;) {
101
        ExitValue value = exit.m_values[i];
102
        int operand = exit.m_values.operandForIndex(i);
103
        
104
        Address address = MacroAssembler::Address(
105
            GPRInfo::callFrameRegister, operand * sizeof(EncodedJSValue));
106
        
107
        switch (value.kind()) {
108
        case ExitValueDead:
109
            jit.store64(MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), address);
110
            break;
111
        case ExitValueConstant:
112
            jit.store64(MacroAssembler::TrustedImm64(JSValue::encode(value.constant())), address);
113
            break;
114
        case ExitValueInJSStack:
115
            break;
116
        case ExitValueInJSStackAsInt32:
117
            jit.load32(
118
                address.withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)),
119
                GPRInfo::regT0);
120
            jit.or64(GPRInfo::tagTypeNumber, GPRInfo::regT0);
121
            jit.store64(GPRInfo::regT0, address);
122
            break;
123
        case ExitValueInJSStackAsDouble:
124
            jit.loadDouble(address, FPRInfo::fpRegT0);
125
            jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
126
            jit.store64(GPRInfo::regT0, address);
127
            break;
128
        case ExitValueArgument:
129
            break;
130
        default:
131
            RELEASE_ASSERT_NOT_REACHED();
132
            break;
133
        }
134
    }
135
    
136
    handleExitCounts(jit, exit);
137
    reifyInlinedCallFrames(jit, exit);
138
    adjustAndJumpToTarget(jit, exit);
139
    
140
    LinkBuffer patchBuffer(*globalData, &jit, codeBlock);
141
    exit.m_code = FINALIZE_CODE_IF(
142
        shouldShowDisassembly(),
143
        patchBuffer,
144
        ("FTL OSR exit #%u (bc#%u, %s) from %s",
145
            exitID, exit.m_codeOrigin.bytecodeIndex,
146
            exitKindToString(exit.m_kind), toCString(*codeBlock).data())); 
147
}
148
149
extern "C" void* compileFTLOSRExit(ExecState* exec, unsigned exitID)
150
{
151
    SamplingRegion samplingRegion("FTL OSR Exit Compilation");
152
    
153
    CodeBlock* codeBlock = exec->codeBlock();
154
    
155
    ASSERT(codeBlock);
156
    ASSERT(codeBlock->getJITType() == JITCode::FTLJIT);
157
    
158
    JSGlobalData* globalData = &exec->globalData();
159
    
160
    OSRExit& exit = codeBlock->getJITCode()->ftl()->osrExit[exitID];
161
    
162
    prepareCodeOriginForOSRExit(exit.m_codeOrigin);
163
    
164
    compileStub(exitID, exit, globalData, codeBlock);
165
    
166
    RepatchBuffer repatchBuffer(codeBlock);
167
    repatchBuffer.relink(
168
        exit.codeLocationForRepatch(codeBlock), CodeLocationLabel(exit.m_code.code()));
169
    
170
    return exit.m_code.code().executableAddress();
171
}
172
173
} } // namespace JSC::FTL
174
175
#endif // ENABLE(FTL_JIT)
176
- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.h +44 lines
Line 0 Source/JavaScriptCore/ftl/FTLOSRExitCompiler.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 FTLOSRExitCompiler_h
27
#define FTLOSRExitCompiler_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
namespace JSC { namespace FTL {
34
35
// Takes the call frame and the index of the exit, and returns the address to
36
// jump to.
37
extern "C" void* DFG_OPERATION compileFTLOSRExit(ExecState*, unsigned exitID) WTF_INTERNAL;
38
39
} } // namespace JSC::FTL
40
41
#endif // ENABLE(FTL_JIT)
42
43
#endif // FTLOSRExitCompiler_h
44
- Source/JavaScriptCore/ftl/FTLOutput.h -2 / +11 lines
Lines 135-153 public: Source/JavaScriptCore/ftl/FTLOutput.h_sec1
135
    LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); }
135
    LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); }
136
    LValue intCast(LValue value, LType type) { return buildIntCast(m_builder, value, type); }
136
    LValue intCast(LValue value, LType type) { return buildIntCast(m_builder, value, type); }
137
    LValue castToInt32(LValue value) { return intCast(value, int32); }
137
    LValue castToInt32(LValue value) { return intCast(value, int32); }
138
    LValue intToPtr(LValue value, LType type) { return buildIntToPtr(m_builder, value, type); }
138
    
139
    
139
    LValue get(LValue reference) { return buildLoad(m_builder, reference); }
140
    LValue get(LValue reference) { return buildLoad(m_builder, reference); }
140
    LValue set(LValue value, LValue reference) { return buildStore(m_builder, value, reference); }
141
    LValue set(LValue value, LValue reference) { return buildStore(m_builder, value, reference); }
141
    
142
    
142
    LValue load(TypedPointer pointer, LType refType)
143
    LValue load(TypedPointer pointer, LType refType)
143
    {
144
    {
144
        LValue result = get(buildIntToPtr(m_builder, pointer.value(), refType));
145
        LValue result = get(intToPtr(pointer.value(), refType));
145
        pointer.heap().decorateInstruction(result, *m_heaps);
146
        pointer.heap().decorateInstruction(result, *m_heaps);
146
        return result;
147
        return result;
147
    }
148
    }
148
    void store(LValue value, TypedPointer pointer, LType refType)
149
    void store(LValue value, TypedPointer pointer, LType refType)
149
    {
150
    {
150
        LValue result = set(value, buildIntToPtr(m_builder, pointer.value(), refType));
151
        LValue result = set(value, intToPtr(pointer.value(), refType));
151
        pointer.heap().decorateInstruction(result, *m_heaps);
152
        pointer.heap().decorateInstruction(result, *m_heaps);
152
    }
153
    }
153
    
154
    
Lines 244-253 public: Source/JavaScriptCore/ftl/FTLOutput.h_sec2
244
    LValue select(LValue value, LValue taken, LValue notTaken) { return buildSelect(m_builder, value, taken, notTaken); }
245
    LValue select(LValue value, LValue taken, LValue notTaken) { return buildSelect(m_builder, value, taken, notTaken); }
245
    LValue extractValue(LValue aggVal, unsigned index) { return buildExtractValue(m_builder, aggVal, index); }
246
    LValue extractValue(LValue aggVal, unsigned index) { return buildExtractValue(m_builder, aggVal, index); }
246
    
247
    
248
    template<typename VectorType>
249
    LValue call(LValue function, const VectorType& vector) { return buildCall(m_builder, function, vector); }
247
    LValue call(LValue function) { return buildCall(m_builder, function); }
250
    LValue call(LValue function) { return buildCall(m_builder, function); }
248
    LValue call(LValue function, LValue arg1) { return buildCall(m_builder, function, arg1); }
251
    LValue call(LValue function, LValue arg1) { return buildCall(m_builder, function, arg1); }
249
    LValue call(LValue function, LValue arg1, LValue arg2) { return buildCall(m_builder, function, arg1, arg2); }
252
    LValue call(LValue function, LValue arg1, LValue arg2) { return buildCall(m_builder, function, arg1, arg2); }
250
    
253
    
254
    LValue convertToTailCall(LValue call)
255
    {
256
        setTailCall(call, IsTailCall);
257
        return true;
258
    }
259
    
251
    void jump(LBasicBlock destination) { buildBr(m_builder, destination); }
260
    void jump(LBasicBlock destination) { buildBr(m_builder, destination); }
252
    void branch(LValue condition, LBasicBlock taken, LBasicBlock notTaken) { buildCondBr(m_builder, condition, taken, notTaken); }
261
    void branch(LValue condition, LBasicBlock taken, LBasicBlock notTaken) { buildCondBr(m_builder, condition, taken, notTaken); }
253
    void ret(LValue value) { buildRet(m_builder, value); }
262
    void ret(LValue value) { buildRet(m_builder, value); }
- Source/JavaScriptCore/ftl/FTLState.h +2 lines
Lines 33-38 Source/JavaScriptCore/ftl/FTLState.h_sec1
33
#include "DFGGraph.h"
33
#include "DFGGraph.h"
34
#include "FTLAbbreviations.h"
34
#include "FTLAbbreviations.h"
35
#include "FTLJITCode.h"
35
#include "FTLJITCode.h"
36
#include "FTLOSRExitCompilationInfo.h"
36
#include <wtf/Noncopyable.h>
37
#include <wtf/Noncopyable.h>
37
38
38
namespace JSC { namespace FTL {
39
namespace JSC { namespace FTL {
Lines 49-54 public: Source/JavaScriptCore/ftl/FTLState.h_sec2
49
    LModule module;
50
    LModule module;
50
    LValue function;
51
    LValue function;
51
    RefPtr<JITCode> jitCode;
52
    RefPtr<JITCode> jitCode;
53
    Vector<OSRExitCompilationInfo> osrExit;
52
    
54
    
53
    void dumpState(const char* when);
55
    void dumpState(const char* when);
54
};
56
};
- Source/JavaScriptCore/ftl/FTLThunks.cpp +76 lines
Line 0 Source/JavaScriptCore/ftl/FTLThunks.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 "FTLThunks.h"
28
29
#if ENABLE(FTL_JIT)
30
31
namespace JSC { namespace FTL {
32
33
MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData* globalData)
34
{
35
    MacroAssembler jit;
36
    
37
    size_t scratchSize = sizeof(EncodedJSValue) * (GPRInfo::numberOfArgumentRegisters + FPRInfo::numberOfArgumentRegisters);
38
    ScratchBuffer* scratchBuffer = globalData->scratchBufferForSize(scratchSize);
39
    EncodedJSValue* buffer = static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer());
40
    
41
    for (unsigned i = 0; i < GPRInfo::numberOfArgumentRegisters; ++i)
42
        jit.store64(GPRInfo::toArgumentRegister(i), buffer + i);
43
    for (unsigned i = 0; i < FPRInfo::numberOfArgumentRegisters; ++i) {
44
        jit.move(MacroAssembler::TrustedImmPtr(buffer + GPRInfo::numberOfArgumentRegisters + i), GPRInfo::nonArgGPR1);
45
        jit.storeDouble(FPRInfo::toArgumentRegister(i), GPRInfo::nonArgGPR1);
46
    }
47
    
48
    // Tell GC mark phase how much of the scratch buffer is active during call.
49
    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::nonArgGPR1);
50
    jit.storePtr(MacroAssembler::TrustedImmPtr(scratchSize), GPRInfo::nonArgGPR1);
51
52
    // argument 0 is already the call frame.
53
    jit.move(GPRInfo::nonArgGPR0, GPRInfo::argumentGPR1);
54
    MacroAssembler::Call functionCall = jit.call();
55
    
56
    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::nonPreservedNonReturnGPR);
57
    jit.storePtr(MacroAssembler::TrustedImmPtr(0), GPRInfo::nonPreservedNonReturnGPR);
58
    
59
    for (unsigned i = 0; i < FPRInfo::numberOfArgumentRegisters; ++i) {
60
        jit.move(MacroAssembler::TrustedImmPtr(buffer + GPRInfo::numberOfArgumentRegisters + i), GPRInfo::nonPreservedNonReturnGPR);
61
        jit.loadDouble(GPRInfo::nonPreservedNonReturnGPR, FPRInfo::toArgumentRegister(i));
62
    }
63
    for (unsigned i = 0; i < GPRInfo::numberOfArgumentRegisters; ++i)
64
        jit.load64(buffer + i, GPRInfo::toArgumentRegister(i));
65
    
66
    jit.jump(GPRInfo::returnValueGPR);
67
    
68
    LinkBuffer patchBuffer(*globalData, &jit, GLOBAL_THUNK_ID);
69
    patchBuffer.link(functionCall, compileFTLOSRExit);
70
    return FINALIZE_CODE(patchBuffer, ("FTL OSR exit generation thunk"));
71
}
72
73
} } // namespace JSC::FTL
74
75
#endif // ENABLE(FTL_JIT)
76
- Source/JavaScriptCore/ftl/FTLThunks.h +47 lines
Line 0 Source/JavaScriptCore/ftl/FTLThunks.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 FTLThunks_h
27
#define FTLThunks_h
28
29
#include <wtf/Platform.h>
30
31
#if ENABLE(FTL_JIT)
32
33
#include "MacroAssemblerCodeRef.h"
34
35
namespace JSC {
36
37
class JSGlobalData;
38
39
namespace FTL {
40
41
MacroAssemblerCodeRef osrExitGenerationThunkGenerator(JSGlobalData*);
42
43
} } // namespace JSC::FTL
44
45
#endif // ENABLE(FTL_JIT)
46
47
#endif // FTLTHunks_h
- 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