- Source/JavaScriptCore/ChangeLog +19 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2014-01-27  Filip Pizlo  <fpizlo@apple.com>
2
3
        FTL should do polyvariant PutById inlining
4
        https://bugs.webkit.org/show_bug.cgi?id=127692
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * bytecode/PutByIdStatus.cpp:
9
        (JSC::PutByIdStatus::hasExitSite):
10
        (JSC::PutByIdStatus::computeFor):
11
        (JSC::PutByIdStatus::computeForStubInfo):
12
        * bytecode/PutByIdStatus.h:
13
        * dfg/DFGByteCodeParser.cpp:
14
        (JSC::DFG::ByteCodeParser::parseBlock):
15
        * tests/stress/simple-polyvariant-put-by-id-inlining-example.js: Added.
16
        (foo):
17
        (fuzz):
18
        (bar):
19
1
2014-01-26  Filip Pizlo  <fpizlo@apple.com>
20
2014-01-26  Filip Pizlo  <fpizlo@apple.com>
2
21
3
        FTL should do polyvariant GetById inlining
22
        FTL should do polyvariant GetById inlining
- Source/JavaScriptCore/bytecode/PutByIdStatus.cpp -10 / +41 lines
Lines 35-46 Source/JavaScriptCore/bytecode/PutByIdStatus.cpp_sec1
35
35
36
namespace JSC {
36
namespace JSC {
37
37
38
bool PutByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex)
38
bool PutByIdStatus::hasExitSite(const ConcurrentJITLocker& locker, CodeBlock* profiledBlock, unsigned bytecodeIndex, ExitingJITType exitType)
39
{
39
{
40
    return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache))
40
    return profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache, exitType))
41
        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint))
41
        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCacheWatchpoint, exitType))
42
        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache))
42
        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCache, exitType))
43
        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint));
43
        || profiledBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadWeakConstantCacheWatchpoint, exitType));
44
}
44
}
45
45
46
PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, StringImpl* uid)
46
PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, StringImpl* uid)
Lines 102-110 PutByIdStatus PutByIdStatus::computeFor( Source/JavaScriptCore/bytecode/PutByIdStatus.cpp_sec2
102
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
102
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
103
    
103
    
104
    StructureStubInfo* stubInfo = map.get(CodeOrigin(bytecodeIndex));
104
    StructureStubInfo* stubInfo = map.get(CodeOrigin(bytecodeIndex));
105
    if (!stubInfo || !stubInfo->seen)
105
    PutByIdStatus result = computeForStubInfo(locker, profiledBlock, stubInfo, uid);
106
    if (!result)
106
        return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
107
        return computeFromLLInt(profiledBlock, bytecodeIndex, uid);
107
    
108
    
109
    return result;
110
#else // ENABLE(JIT)
111
    UNUSED_PARAM(map);
112
    return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
113
#endif // ENABLE(JIT)
114
}
115
116
PutByIdStatus PutByIdStatus::computeForStubInfo(const ConcurrentJITLocker&, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, StringImpl* uid)
117
{
118
    if (!stubInfo || !stubInfo->seen)
119
        return PutByIdStatus();
120
    
108
    if (stubInfo->resetByGC)
121
    if (stubInfo->resetByGC)
109
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
122
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
110
123
Lines 151-160 PutByIdStatus PutByIdStatus::computeFor( Source/JavaScriptCore/bytecode/PutByIdStatus.cpp_sec3
151
        // we could do about it.
164
        // we could do about it.
152
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
165
        return PutByIdStatus(TakesSlowPath, 0, 0, 0, invalidOffset);
153
    }
166
    }
154
#else // ENABLE(JIT)
167
}
155
    UNUSED_PARAM(map);
168
156
    return PutByIdStatus(NoInformation, 0, 0, 0, invalidOffset);
169
PutByIdStatus PutByIdStatus::computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin codeOrigin, StringImpl* uid)
157
#endif // ENABLE(JIT)
170
{
171
    if (dfgBlock) {
172
        {
173
            ConcurrentJITLocker locker(baselineBlock->m_lock);
174
            if (hasExitSite(locker, baselineBlock, codeOrigin.bytecodeIndex, ExitFromFTL))
175
                return PutByIdStatus(TakesSlowPath);
176
        }
177
            
178
        PutByIdStatus result;
179
        {
180
            ConcurrentJITLocker locker(dfgBlock->m_lock);
181
            result = computeForStubInfo(locker, dfgBlock, dfgMap.get(codeOrigin), uid);
182
        }
183
        
184
        if (result.isSet())
185
            return result;
186
    }
187
    
188
    return computeFor(baselineBlock, baselineMap, codeOrigin.bytecodeIndex, uid);
158
}
189
}
159
190
160
PutByIdStatus PutByIdStatus::computeFor(VM& vm, JSGlobalObject* globalObject, Structure* structure, StringImpl* uid, bool isDirect)
191
PutByIdStatus PutByIdStatus::computeFor(VM& vm, JSGlobalObject* globalObject, Structure* structure, StringImpl* uid, bool isDirect)
- Source/JavaScriptCore/bytecode/PutByIdStatus.h -1 / +5 lines
Lines 26-31 Source/JavaScriptCore/bytecode/PutByIdStatus.h_sec1
26
#ifndef PutByIdStatus_h
26
#ifndef PutByIdStatus_h
27
#define PutByIdStatus_h
27
#define PutByIdStatus_h
28
28
29
#include "ExitingJITType.h"
29
#include "IntendedStructureChain.h"
30
#include "IntendedStructureChain.h"
30
#include "PropertyOffset.h"
31
#include "PropertyOffset.h"
31
#include "StructureStubInfo.h"
32
#include "StructureStubInfo.h"
Lines 94-99 public: Source/JavaScriptCore/bytecode/PutByIdStatus.h_sec2
94
    static PutByIdStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex, StringImpl* uid);
95
    static PutByIdStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex, StringImpl* uid);
95
    static PutByIdStatus computeFor(VM&, JSGlobalObject*, Structure*, StringImpl* uid, bool isDirect);
96
    static PutByIdStatus computeFor(VM&, JSGlobalObject*, Structure*, StringImpl* uid, bool isDirect);
96
    
97
    
98
    static PutByIdStatus computeFor(CodeBlock* baselineBlock, CodeBlock* dfgBlock, StubInfoMap& baselineMap, StubInfoMap& dfgMap, CodeOrigin, StringImpl* uid);
99
    
97
    State state() const { return m_state; }
100
    State state() const { return m_state; }
98
    
101
    
99
    bool isSet() const { return m_state != NoInformation; }
102
    bool isSet() const { return m_state != NoInformation; }
Lines 108-114 public: Source/JavaScriptCore/bytecode/PutByIdStatus.h_sec3
108
    PropertyOffset offset() const { return m_offset; }
111
    PropertyOffset offset() const { return m_offset; }
109
    
112
    
110
private:
113
private:
111
    static bool hasExitSite(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex);
114
    static bool hasExitSite(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex, ExitingJITType = ExitFromAnything);
115
    static PutByIdStatus computeForStubInfo(const ConcurrentJITLocker&, CodeBlock*, StructureStubInfo*, StringImpl* uid);
112
    static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, StringImpl* uid);
116
    static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, StringImpl* uid);
113
    
117
    
114
    State m_state;
118
    State m_state;
- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp -2 / +3 lines
Lines 2541-2548 bool ByteCodeParser::parseBlock(unsigned Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp_sec1
2541
            bool direct = currentInstruction[8].u.operand;
2541
            bool direct = currentInstruction[8].u.operand;
2542
2542
2543
            PutByIdStatus putByIdStatus = PutByIdStatus::computeFor(
2543
            PutByIdStatus putByIdStatus = PutByIdStatus::computeFor(
2544
                m_inlineStackTop->m_profiledBlock, m_inlineStackTop->m_stubInfos,
2544
                m_inlineStackTop->m_profiledBlock, m_dfgCodeBlock,
2545
                m_currentIndex, m_graph.identifiers()[identifierNumber]);
2545
                m_inlineStackTop->m_stubInfos, m_dfgStubInfos,
2546
                currentCodeOrigin(), m_graph.identifiers()[identifierNumber]);
2546
            bool canCountAsInlined = true;
2547
            bool canCountAsInlined = true;
2547
            if (!putByIdStatus.isSet()) {
2548
            if (!putByIdStatus.isSet()) {
2548
                addToGraph(ForceOSRExit);
2549
                addToGraph(ForceOSRExit);
- Source/JavaScriptCore/tests/stress/simple-polyvariant-put-by-id-inlining-example.js +26 lines
Line 0 Source/JavaScriptCore/tests/stress/simple-polyvariant-put-by-id-inlining-example.js_sec1
1
function foo(o) {
2
    bar(o);
3
}
4
5
function fuzz(o) {
6
    bar(o);
7
}
8
9
function bar(o) {
10
    o.f = 42;
11
}
12
13
noInline(foo);
14
noInline(fuzz);
15
16
for (var i = 0; i < 100000; ++i) {
17
    var o = {};
18
    foo(o);
19
    if (o.f != 42)
20
        throw "Error: bad result: " + o.f;
21
    o = {f:23};
22
    var result = fuzz(o);
23
    if (o.f != 42)
24
        throw "Error: bad result: " + o.f;
25
}
26

Return to Bug 127692