| Differences between
and this patch
- Source/JavaScriptCore/CMakeLists.txt +1 lines
Lines 129-134 set(JavaScriptCore_SOURCES Source/JavaScriptCore/CMakeLists.txt_sec1
129
    b3/B3OpaqueByproducts.cpp
129
    b3/B3OpaqueByproducts.cpp
130
    b3/B3Opcode.cpp
130
    b3/B3Opcode.cpp
131
    b3/B3Origin.cpp
131
    b3/B3Origin.cpp
132
    b3/B3OriginDump.cpp
132
    b3/B3PatchpointSpecial.cpp
133
    b3/B3PatchpointSpecial.cpp
133
    b3/B3PatchpointValue.cpp
134
    b3/B3PatchpointValue.cpp
134
    b3/B3PhaseScope.cpp
135
    b3/B3PhaseScope.cpp
- Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +4 lines
Lines 380-385 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec1
380
		0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
380
		0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
381
		0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */; };
381
		0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */; };
382
		0F4C91681C2B3D68004341A6 /* AirFixSpillSlotZDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */; };
382
		0F4C91681C2B3D68004341A6 /* AirFixSpillSlotZDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */; };
383
		0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */; };
383
		0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
384
		0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
384
		0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; };
385
		0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; };
385
		0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; };
386
		0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; };
Lines 2543-2548 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec2
2543
		0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; };
2544
		0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; };
2544
		0F4C91651C29F4F2004341A6 /* B3OriginDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3OriginDump.h; path = b3/B3OriginDump.h; sourceTree = "<group>"; };
2545
		0F4C91651C29F4F2004341A6 /* B3OriginDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3OriginDump.h; path = b3/B3OriginDump.h; sourceTree = "<group>"; };
2545
		0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirFixSpillSlotZDef.h; path = b3/air/AirFixSpillSlotZDef.h; sourceTree = "<group>"; };
2546
		0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirFixSpillSlotZDef.h; path = b3/air/AirFixSpillSlotZDef.h; sourceTree = "<group>"; };
2547
		0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3OriginDump.cpp; path = b3/B3OriginDump.cpp; sourceTree = "<group>"; };
2546
		0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
2548
		0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
2547
		0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
2549
		0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
2548
		0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = "<group>"; };
2550
		0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = "<group>"; };
Lines 4783-4788 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec3
4783
				0FEC84D81BDACDAC0080FF74 /* B3Opcode.h */,
4785
				0FEC84D81BDACDAC0080FF74 /* B3Opcode.h */,
4784
				0FEC84D91BDACDAC0080FF74 /* B3Origin.cpp */,
4786
				0FEC84D91BDACDAC0080FF74 /* B3Origin.cpp */,
4785
				0FEC84DA1BDACDAC0080FF74 /* B3Origin.h */,
4787
				0FEC84DA1BDACDAC0080FF74 /* B3Origin.h */,
4788
				0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */,
4786
				0F4C91651C29F4F2004341A6 /* B3OriginDump.h */,
4789
				0F4C91651C29F4F2004341A6 /* B3OriginDump.h */,
4787
				0FEC84DB1BDACDAC0080FF74 /* B3PatchpointSpecial.cpp */,
4790
				0FEC84DB1BDACDAC0080FF74 /* B3PatchpointSpecial.cpp */,
4788
				0FEC84DC1BDACDAC0080FF74 /* B3PatchpointSpecial.h */,
4791
				0FEC84DC1BDACDAC0080FF74 /* B3PatchpointSpecial.h */,
Lines 8912-8917 Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj_sec4
8912
				0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */,
8915
				0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */,
8913
				0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */,
8916
				0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */,
8914
				0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
8917
				0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
8918
				0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */,
8915
				FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */,
8919
				FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */,
8916
				0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
8920
				0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
8917
				0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
8921
				0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
- Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp -1 / +6 lines
Lines 1-5 Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
2
 * Copyright (C) 2015-2016 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 39-44 void ArgumentRegValue::dumpMeta(CommaPri Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp_sec2
39
    out.print(comma, m_reg);
39
    out.print(comma, m_reg);
40
}
40
}
41
41
42
Value* ArgumentRegValue::cloneImpl() const
43
{
44
    return new ArgumentRegValue(*this);
45
}
46
42
} } // namespace JSC::B3
47
} } // namespace JSC::B3
43
48
44
#endif // ENABLE(B3_JIT)
49
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3ArgumentRegValue.h -1 / +3 lines
Lines 1-5 Source/JavaScriptCore/b3/B3ArgumentRegValue.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
2
 * Copyright (C) 2015-2016 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 44-49 public: Source/JavaScriptCore/b3/B3ArgumentRegValue.h_sec2
44
protected:
44
protected:
45
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
45
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
46
46
47
    Value* cloneImpl() const override;
48
47
private:
49
private:
48
    friend class Procedure;
50
    friend class Procedure;
49
51
- Source/JavaScriptCore/b3/B3BlockInsertionSet.h -2 / +2 lines
Lines 61-68 public: Source/JavaScriptCore/b3/B3BlockInsertionSet.h_sec1
61
    // everything at and after valueIndex. If the optional InsertionSet is provided, it will get
61
    // everything at and after valueIndex. If the optional InsertionSet is provided, it will get
62
    // executed on the newly created block - this makes sense if you had previously inserted
62
    // executed on the newly created block - this makes sense if you had previously inserted
63
    // things into the original block, since the newly created block will be indexed identically
63
    // things into the original block, since the newly created block will be indexed identically
64
    // to hold this block was indexed for all values prior to valueIndex. After this runs, it
64
    // to how this block was indexed for all values prior to valueIndex. After this runs, it sets
65
    // sets valueIndex to zero. This allows you to use this method for things like:
65
    // valueIndex to zero. This allows you to use this method for things like:
66
    //
66
    //
67
    // for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
67
    // for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
68
    //     Value* value = block->at(valueIndex);
68
    //     Value* value = block->at(valueIndex);
- Source/JavaScriptCore/b3/B3CCallValue.cpp +5 lines
Lines 34-39 CCallValue::~CCallValue() Source/JavaScriptCore/b3/B3CCallValue.cpp_sec1
34
{
34
{
35
}
35
}
36
36
37
Value* CCallValue::cloneImpl() const
38
{
39
    return new CCallValue(*this);
40
}
41
37
} } // namespace JSC::B3
42
} } // namespace JSC::B3
38
43
39
#endif // ENABLE(B3_JIT)
44
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3CCallValue.h +3 lines
Lines 41-46 public: Source/JavaScriptCore/b3/B3CCallValue.h_sec1
41
41
42
    Effects effects { Effects::forCall() };
42
    Effects effects { Effects::forCall() };
43
43
44
protected:
45
    Value* cloneImpl() const override;
46
    
44
private:
47
private:
45
    friend class Procedure;
48
    friend class Procedure;
46
49
- Source/JavaScriptCore/b3/B3CheckValue.cpp +5 lines
Lines 40-45 void CheckValue::convertToAdd() Source/JavaScriptCore/b3/B3CheckValue.cpp_sec1
40
    m_opcode = CheckAdd;
40
    m_opcode = CheckAdd;
41
}
41
}
42
42
43
Value* CheckValue::cloneImpl() const
44
{
45
    return new CheckValue(*this);
46
}
47
43
// Use this form for CheckAdd, CheckSub, and CheckMul.
48
// Use this form for CheckAdd, CheckSub, and CheckMul.
44
CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* left, Value* right)
49
CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* left, Value* right)
45
    : StackmapValue(index, CheckedOpcode, opcode, left->type(), origin)
50
    : StackmapValue(index, CheckedOpcode, opcode, left->type(), origin)
- Source/JavaScriptCore/b3/B3CheckValue.h +3 lines
Lines 51-56 public: Source/JavaScriptCore/b3/B3CheckValue.h_sec1
51
51
52
    void convertToAdd();
52
    void convertToAdd();
53
53
54
protected:
55
    Value* cloneImpl() const override;
56
    
54
private:
57
private:
55
    friend class Procedure;
58
    friend class Procedure;
56
59
- Source/JavaScriptCore/b3/B3Const32Value.cpp -1 / +6 lines
Lines 1-5 Source/JavaScriptCore/b3/B3Const32Value.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
2
 * Copyright (C) 2015-2016 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 241-246 void Const32Value::dumpMeta(CommaPrinter Source/JavaScriptCore/b3/B3Const32Value.cpp_sec2
241
    out.print(comma, m_value);
241
    out.print(comma, m_value);
242
}
242
}
243
243
244
Value* Const32Value::cloneImpl() const
245
{
246
    return new Const32Value(*this);
247
}
248
244
} } // namespace JSC::B3
249
} } // namespace JSC::B3
245
250
246
#endif // ENABLE(B3_JIT)
251
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3Const32Value.h -1 / +3 lines
Lines 1-5 Source/JavaScriptCore/b3/B3Const32Value.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
2
 * Copyright (C) 2015-2016 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 73-78 public: Source/JavaScriptCore/b3/B3Const32Value.h_sec2
73
protected:
73
protected:
74
    JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&, PrintStream&) const override;
74
    JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&, PrintStream&) const override;
75
75
76
    Value* cloneImpl() const override;
77
76
    friend class Procedure;
78
    friend class Procedure;
77
79
78
    Const32Value(unsigned index, Origin origin, int32_t value)
80
    Const32Value(unsigned index, Origin origin, int32_t value)
- Source/JavaScriptCore/b3/B3Const64Value.cpp +5 lines
Lines 241-246 void Const64Value::dumpMeta(CommaPrinter Source/JavaScriptCore/b3/B3Const64Value.cpp_sec1
241
    out.print(comma, m_value);
241
    out.print(comma, m_value);
242
}
242
}
243
243
244
Value* Const64Value::cloneImpl() const
245
{
246
    return new Const64Value(*this);
247
}
248
244
} } // namespace JSC::B3
249
} } // namespace JSC::B3
245
250
246
#endif // ENABLE(B3_JIT)
251
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3Const64Value.h +2 lines
Lines 73-78 public: Source/JavaScriptCore/b3/B3Const64Value.h_sec1
73
protected:
73
protected:
74
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
74
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
75
75
76
    Value* cloneImpl() const override;
77
76
    friend class Procedure;
78
    friend class Procedure;
77
79
78
    Const64Value(unsigned index, Origin origin, int64_t value)
80
    Const64Value(unsigned index, Origin origin, int64_t value)
- Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp +5 lines
Lines 175-180 void ConstDoubleValue::dumpMeta(CommaPri Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp_sec1
175
    out.printf("%le", m_value);
175
    out.printf("%le", m_value);
176
}
176
}
177
177
178
Value* ConstDoubleValue::cloneImpl() const
179
{
180
    return new ConstDoubleValue(*this);
181
}
182
178
} } // namespace JSC::B3
183
} } // namespace JSC::B3
179
184
180
#endif // ENABLE(B3_JIT)
185
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3ConstDoubleValue.h +2 lines
Lines 65-70 public: Source/JavaScriptCore/b3/B3ConstDoubleValue.h_sec1
65
protected:
65
protected:
66
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
66
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
67
67
68
    Value* cloneImpl() const override;
69
68
private:
70
private:
69
    friend class Procedure;
71
    friend class Procedure;
70
72
- Source/JavaScriptCore/b3/B3ConstFloatValue.cpp +5 lines
Lines 157-162 void ConstFloatValue::dumpMeta(CommaPrin Source/JavaScriptCore/b3/B3ConstFloatValue.cpp_sec1
157
    out.printf("%le", m_value);
157
    out.printf("%le", m_value);
158
}
158
}
159
159
160
Value* ConstFloatValue::cloneImpl() const
161
{
162
    return new ConstFloatValue(*this);
163
}
164
160
} } // namespace JSC::B3
165
} } // namespace JSC::B3
161
166
162
#endif // ENABLE(B3_JIT)
167
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3ConstFloatValue.h +2 lines
Lines 63-68 public: Source/JavaScriptCore/b3/B3ConstFloatValue.h_sec1
63
protected:
63
protected:
64
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
64
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
65
65
66
    Value* cloneImpl() const override;
67
66
private:
68
private:
67
    friend class Procedure;
69
    friend class Procedure;
68
70
- Source/JavaScriptCore/b3/B3ControlValue.cpp +5 lines
Lines 83-88 void ControlValue::dumpMeta(CommaPrinter Source/JavaScriptCore/b3/B3ControlValue.cpp_sec1
83
        out.print(comma, successor);
83
        out.print(comma, successor);
84
}
84
}
85
85
86
Value* ControlValue::cloneImpl() const
87
{
88
    return new ControlValue(*this);
89
}
90
86
} } // namespace JSC::B3
91
} } // namespace JSC::B3
87
92
88
#endif // ENABLE(B3_JIT)
93
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3ControlValue.h +2 lines
Lines 93-98 public: Source/JavaScriptCore/b3/B3ControlValue.h_sec1
93
protected:
93
protected:
94
    JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&, PrintStream&) const override;
94
    JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&, PrintStream&) const override;
95
95
96
    Value* cloneImpl() const override;
97
96
    // Use this for subclasses.
98
    // Use this for subclasses.
97
    template<typename... Arguments>
99
    template<typename... Arguments>
98
    ControlValue(unsigned index, Opcode opcode, Type type, Origin origin, Arguments... arguments)
100
    ControlValue(unsigned index, Opcode opcode, Type type, Origin origin, Arguments... arguments)
- Source/JavaScriptCore/b3/B3MemoryValue.cpp +5 lines
Lines 61-66 void MemoryValue::dumpMeta(CommaPrinter& Source/JavaScriptCore/b3/B3MemoryValue.cpp_sec1
61
        out.print(comma, "offset = ", m_offset);
61
        out.print(comma, "offset = ", m_offset);
62
}
62
}
63
63
64
Value* MemoryValue::cloneImpl() const
65
{
66
    return new MemoryValue(*this);
67
}
68
64
} } // namespace JSC::B3
69
} } // namespace JSC::B3
65
70
66
#endif // ENABLE(B3_JIT)
71
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3MemoryValue.h +2 lines
Lines 65-70 public: Source/JavaScriptCore/b3/B3MemoryValue.h_sec1
65
protected:
65
protected:
66
    void dumpMeta(CommaPrinter& comma, PrintStream&) const override;
66
    void dumpMeta(CommaPrinter& comma, PrintStream&) const override;
67
67
68
    Value* cloneImpl() const override;
69
68
private:
70
private:
69
    friend class Procedure;
71
    friend class Procedure;
70
72
- Source/JavaScriptCore/b3/B3OriginDump.cpp +46 lines
Line 0 Source/JavaScriptCore/b3/B3OriginDump.cpp_sec1
1
/*
2
 * Copyright (C) 2016 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 "B3OriginDump.h"
28
29
#if ENABLE(B3_JIT)
30
31
#include "B3Procedure.h"
32
33
namespace JSC { namespace B3 {
34
35
void OriginDump::dump(PrintStream& out) const
36
{
37
    if (m_proc)
38
        m_proc->printOrigin(out, m_origin);
39
    else
40
        out.print(m_origin);
41
}
42
43
} } // namespace JSC::B3
44
45
#endif // ENABLE(B3_JIT)
46
- Source/JavaScriptCore/b3/B3OriginDump.h -8 / +6 lines
Lines 1-5 Source/JavaScriptCore/b3/B3OriginDump.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
2
 * Copyright (C) 2015-2016 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 29-53 Source/JavaScriptCore/b3/B3OriginDump.h_sec2
29
#if ENABLE(B3_JIT)
29
#if ENABLE(B3_JIT)
30
30
31
#include "B3Origin.h"
31
#include "B3Origin.h"
32
#include "B3Procedure.h"
33
32
34
namespace JSC { namespace B3 {
33
namespace JSC { namespace B3 {
35
34
35
class Procedure;
36
36
class OriginDump {
37
class OriginDump {
37
public:
38
public:
38
    OriginDump(const Procedure& proc, Origin origin)
39
    OriginDump(const Procedure* proc, Origin origin)
39
        : m_proc(proc)
40
        : m_proc(proc)
40
        , m_origin(origin)
41
        , m_origin(origin)
41
    {
42
    {
42
    }
43
    }
43
44
44
    void dump(PrintStream& out) const
45
    void dump(PrintStream& out) const;
45
    {
46
        m_proc.printOrigin(out, m_origin);
47
    }
48
46
49
private:
47
private:
50
    const Procedure& m_proc;
48
    const Procedure* m_proc;
51
    Origin m_origin;
49
    Origin m_origin;
52
};
50
};
53
51
- Source/JavaScriptCore/b3/B3PatchpointValue.cpp +5 lines
Lines 44-49 void PatchpointValue::dumpMeta(CommaPrin Source/JavaScriptCore/b3/B3PatchpointValue.cpp_sec1
44
        out.print(comma, "numFPScratchRegisters = ", numFPScratchRegisters);
44
        out.print(comma, "numFPScratchRegisters = ", numFPScratchRegisters);
45
}
45
}
46
46
47
Value* PatchpointValue::cloneImpl() const
48
{
49
    return new PatchpointValue(*this);
50
}
51
47
PatchpointValue::PatchpointValue(unsigned index, Type type, Origin origin)
52
PatchpointValue::PatchpointValue(unsigned index, Type type, Origin origin)
48
    : Base(index, CheckedOpcode, Patchpoint, type, origin)
53
    : Base(index, CheckedOpcode, Patchpoint, type, origin)
49
    , effects(Effects::forCall())
54
    , effects(Effects::forCall())
- Source/JavaScriptCore/b3/B3PatchpointValue.h +2 lines
Lines 65-70 public: Source/JavaScriptCore/b3/B3PatchpointValue.h_sec1
65
protected:
65
protected:
66
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
66
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
67
67
68
    Value* cloneImpl() const override;
69
68
private:
70
private:
69
    friend class Procedure;
71
    friend class Procedure;
70
72
- Source/JavaScriptCore/b3/B3Procedure.cpp -1 / +11 lines
Lines 68-73 BasicBlock* Procedure::addBlock(double f Source/JavaScriptCore/b3/B3Procedure.cpp_sec1
68
    return result;
68
    return result;
69
}
69
}
70
70
71
Value* Procedure::clone(Value* value)
72
{
73
    std::unique_ptr<Value> clone(value->cloneImpl());
74
    Value* result = clone.get();
75
    clone->m_index = addValueIndex();
76
    clone->owner = nullptr;
77
    m_values[clone->m_index] = WTFMove(clone);
78
    return result;
79
}
80
71
Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
81
Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
72
{
82
{
73
    switch (type) {
83
    switch (type) {
Lines 165-171 Vector<BasicBlock*> Procedure::blocksInP Source/JavaScriptCore/b3/B3Procedure.cpp_sec2
165
175
166
void Procedure::deleteValue(Value* value)
176
void Procedure::deleteValue(Value* value)
167
{
177
{
168
    ASSERT(m_values[value->index()].get() == value);
178
    RELEASE_ASSERT(m_values[value->index()].get() == value);
169
    m_valueIndexFreeList.append(value->index());
179
    m_valueIndexFreeList.append(value->index());
170
    m_values[value->index()] = nullptr;
180
    m_values[value->index()] = nullptr;
171
}
181
}
- Source/JavaScriptCore/b3/B3Procedure.h +2 lines
Lines 76-81 public: Source/JavaScriptCore/b3/B3Procedure.h_sec1
76
    template<typename ValueType, typename... Arguments>
76
    template<typename ValueType, typename... Arguments>
77
    ValueType* add(Arguments...);
77
    ValueType* add(Arguments...);
78
78
79
    Value* clone(Value*);
80
79
    Value* addIntConstant(Origin, Type, int64_t value);
81
    Value* addIntConstant(Origin, Type, int64_t value);
80
    Value* addIntConstant(Value*, int64_t value);
82
    Value* addIntConstant(Value*, int64_t value);
81
83
- Source/JavaScriptCore/b3/B3ReduceStrength.cpp +202 lines
Lines 29-34 Source/JavaScriptCore/b3/B3ReduceStrength.cpp_sec1
29
#if ENABLE(B3_JIT)
29
#if ENABLE(B3_JIT)
30
30
31
#include "B3BasicBlockInlines.h"
31
#include "B3BasicBlockInlines.h"
32
#include "B3BlockInsertionSet.h"
32
#include "B3ControlValue.h"
33
#include "B3ControlValue.h"
33
#include "B3Dominators.h"
34
#include "B3Dominators.h"
34
#include "B3IndexSet.h"
35
#include "B3IndexSet.h"
Lines 89-94 public: Source/JavaScriptCore/b3/B3ReduceStrength.cpp_sec2
89
    ReduceStrength(Procedure& proc)
90
    ReduceStrength(Procedure& proc)
90
        : m_proc(proc)
91
        : m_proc(proc)
91
        , m_insertionSet(proc)
92
        , m_insertionSet(proc)
93
        , m_blockInsertionSet(proc)
92
    {
94
    {
93
    }
95
    }
94
96
Lines 117-122 public: Source/JavaScriptCore/b3/B3ReduceStrength.cpp_sec3
117
                m_block = block;
119
                m_block = block;
118
                
120
                
119
                for (m_index = 0; m_index < block->size(); ++m_index) {
121
                for (m_index = 0; m_index < block->size(); ++m_index) {
122
                    if (verbose) {
123
                        dataLog(
124
                            "Looking at ", *block, " #", m_index, ": ",
125
                            deepDump(m_proc, block->at(m_index)), "\n");
126
                    }
120
                    m_value = m_block->at(m_index);
127
                    m_value = m_block->at(m_index);
121
                    m_value->performSubstitution();
128
                    m_value->performSubstitution();
122
                    
129
                    
Lines 126-131 public: Source/JavaScriptCore/b3/B3ReduceStrength.cpp_sec4
126
                m_insertionSet.execute(m_block);
133
                m_insertionSet.execute(m_block);
127
            }
134
            }
128
135
136
            if (m_blockInsertionSet.execute()) {
137
                m_proc.resetReachability();
138
                m_proc.invalidateCFG();
139
                m_dominators = &m_proc.dominators(); // Recompute if necessary.
140
                m_changedCFG = true;
141
            }
142
            
129
            simplifyCFG();
143
            simplifyCFG();
130
144
131
            if (m_changedCFG) {
145
            if (m_changedCFG) {
Lines 1191-1196 private: Source/JavaScriptCore/b3/B3ReduceStrength.cpp_sec5
1191
                && checkValue->child(0)->child(1)->isInt(0)) {
1205
                && checkValue->child(0)->child(1)->isInt(0)) {
1192
                checkValue->child(0) = checkValue->child(0)->child(0);
1206
                checkValue->child(0) = checkValue->child(0)->child(0);
1193
                m_changed = true;
1207
                m_changed = true;
1208
            }
1209
1210
            // If we are checking some bounded-size SSA expression that leads to a Select that
1211
            // has a constant as one of its results, then turn the Select into a Branch and split
1212
            // the code between the Check and the Branch. For example, this:
1213
            //
1214
            //     @a = Select(@p, @x, 42)
1215
            //     @b = Add(@a, 35)
1216
            //     Check(@b)
1217
            //
1218
            // becomes this:
1219
            //
1220
            //     Branch(@p, #truecase, #falsecase)
1221
            //
1222
            //   BB#truecase:
1223
            //     @b_truecase = Add(@x, 35)
1224
            //     Check(@b_truecase)
1225
            //     Upsilon(@x, ^a)
1226
            //     Upsilon(@b_truecase, ^b)
1227
            //     Jump(#continuation)
1228
            //
1229
            //   BB#falsecase:
1230
            //     @b_falsecase = Add(42, 35)
1231
            //     Check(@b_falsecase)
1232
            //     Upsilon(42, ^a)
1233
            //     Upsilon(@b_falsecase, ^b)
1234
            //     Jump(#continuation)
1235
            //
1236
            //   BB#continuation:
1237
            //     @a = Phi()
1238
            //     @b = Phi()
1239
            //
1240
            // The goal of this optimization is to kill a lot of code in one of those basic
1241
            // blocks. This is pretty much guaranteed since one of those blocks will replace all
1242
            // uses of the Select with a constant, and that constant will be transitively used
1243
            // from the check.
1244
            static const unsigned selectSpecializationBound = 3;
1245
            Value* select = findRecentNodeMatching(
1246
                m_value->child(0), selectSpecializationBound,
1247
                [&] (Value* value) -> bool {
1248
                    return value->opcode() == Select
1249
                        && (value->child(1)->isConstant() || value->child(2)->isConstant());
1250
                });
1251
            if (select) {
1252
                specializeSelect(select);
1194
                break;
1253
                break;
1195
            }
1254
            }
1196
            break;
1255
            break;
Lines 1262-1267 private: Source/JavaScriptCore/b3/B3ReduceStrength.cpp_sec6
1262
        }
1321
        }
1263
    }
1322
    }
1264
1323
1324
    // Find a node that:
1325
    //     - functor(node) returns true.
1326
    //     - it's reachable from the given node via children.
1327
    //     - it's in the last "bound" slots in the current basic block.
1328
    // This algorithm is optimized under the assumption that the bound is small.
1329
    template<typename Functor>
1330
    Value* findRecentNodeMatching(Value* start, unsigned bound, const Functor& functor)
1331
    {
1332
        unsigned startIndex = bound < m_index ? m_index - bound : 0;
1333
        Value* result = nullptr;
1334
        start->walk(
1335
            [&] (Value* value) -> Value::WalkStatus {
1336
                bool found = false;
1337
                for (unsigned i = startIndex; i <= m_index; ++i) {
1338
                    if (m_block->at(i) == value)
1339
                        found = true;
1340
                }
1341
                if (!found)
1342
                    return Value::IgnoreChildren;
1343
1344
                if (functor(value)) {
1345
                    result = value;
1346
                    return Value::Stop;
1347
                }
1348
1349
                return Value::Continue;
1350
            });
1351
        return result;
1352
    }
1353
1354
    // This specializes a sequence of code up to a Select. This doesn't work when we're at a
1355
    // terminal. It would be cool to fix that eventually. The main problem is that instead of
1356
    // splitting the block, we should just insert the then/else blocks. We'll have to create
1357
    // double the Phis and double the Upsilons. It'll probably be the sort of optimization that
1358
    // we want to do only after we've done loop optimizations, since this will *definitely*
1359
    // obscure things. In fact, even this simpler form of select specialization will possibly
1360
    // obscure other optimizations. It would be great to have two modes of strength reduction,
1361
    // one that does obscuring optimizations and runs late, and another that does not do
1362
    // obscuring optimizations and runs early.
1363
    // FIXME: Make select specialization handle branches.
1364
    // FIXME: Have a form of strength reduction that does no obscuring optimizations and runs
1365
    // early.
1366
    void specializeSelect(Value* source)
1367
    {
1368
        if (verbose)
1369
            dataLog("Specializing select: ", deepDump(m_proc, source), "\n");
1370
1371
        // This mutates startIndex to account for the fact that m_block got the front of it
1372
        // chopped off.
1373
        BasicBlock* predecessor =
1374
            m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet);
1375
1376
        // Splitting will commit the insertion set, which changes the exact position of the
1377
        // source. That's why we do the search after splitting.
1378
        unsigned startIndex = UINT_MAX;
1379
        for (unsigned i = predecessor->size(); i--;) {
1380
            if (predecessor->at(i) == source) {
1381
                startIndex = i;
1382
                break;
1383
            }
1384
        }
1385
        
1386
        RELEASE_ASSERT(startIndex != UINT_MAX);
1387
1388
        // By BasicBlock convention, caseIndex == 0 => then, caseIndex == 1 => else.
1389
        static const unsigned numCases = 2;
1390
        BasicBlock* cases[numCases];
1391
        for (unsigned i = 0; i < numCases; ++i)
1392
            cases[i] = m_blockInsertionSet.insertBefore(m_block);
1393
1394
        HashMap<Value*, Value*> mappings[2];
1395
1396
        // Save things we want to know about the source.
1397
        Value* predicate = source->child(0);
1398
1399
        for (unsigned i = 0; i < numCases; ++i)
1400
            mappings[i].add(source, source->child(1 + i));
1401
1402
        auto cloneValue = [&] (Value* value) {
1403
            ASSERT(value != source);
1404
1405
            for (unsigned i = 0; i < numCases; ++i) {
1406
                Value* clone = m_proc.clone(value);
1407
                for (Value*& child : clone->children()) {
1408
                    if (Value* newChild = mappings[i].get(child))
1409
                        child = newChild;
1410
                }
1411
                if (value->type() != Void)
1412
                    mappings[i].add(value, clone);
1413
1414
                cases[i]->append(clone);
1415
                if (value->type() != Void)
1416
                    cases[i]->appendNew<UpsilonValue>(m_proc, value->origin(), clone, value);
1417
            }
1418
1419
            value->replaceWithPhi();
1420
        };
1421
1422
        // The jump that the splitter inserted is of no use to us.
1423
        m_proc.deleteValue(predecessor->values().takeLast());
1424
1425
        // Hance the source, it's special.
1426
        for (unsigned i = 0; i < numCases; ++i) {
1427
            cases[i]->appendNew<UpsilonValue>(
1428
                m_proc, source->origin(), source->child(1 + i), source);
1429
        }
1430
        source->replaceWithPhi();
1431
        m_insertionSet.insertValue(m_index, source);
1432
1433
        // Now handle all values between the source and the check.
1434
        for (unsigned i = startIndex + 1; i < predecessor->size(); ++i) {
1435
            Value* value = predecessor->at(i);
1436
            value->owner = nullptr;
1437
1438
            cloneValue(value);
1439
1440
            if (value->type() != Void)
1441
                m_insertionSet.insertValue(m_index, value);
1442
            else
1443
                m_proc.deleteValue(value);
1444
        }
1445
1446
        // Finally, deal with the check.
1447
        cloneValue(m_value);
1448
1449
        // Remove the values from the predecessor.
1450
        predecessor->values().resize(startIndex);
1451
        
1452
        predecessor->appendNew<ControlValue>(
1453
            m_proc, Branch, source->origin(), predicate,
1454
            FrequentedBlock(cases[0]), FrequentedBlock(cases[1]));
1455
1456
        for (unsigned i = 0; i < numCases; ++i) {
1457
            cases[i]->appendNew<ControlValue>(
1458
                m_proc, Jump, m_value->origin(), FrequentedBlock(m_block));
1459
        }
1460
1461
        m_changed = true;
1462
1463
        predecessor->updatePredecessorsAfter();
1464
    }
1465
1265
    // Turn this: Add(constant, value)
1466
    // Turn this: Add(constant, value)
1266
    // Into this: Add(value, constant)
1467
    // Into this: Add(value, constant)
1267
    //
1468
    //
Lines 1609-1614 private: Source/JavaScriptCore/b3/B3ReduceStrength.cpp_sec7
1609
1810
1610
    Procedure& m_proc;
1811
    Procedure& m_proc;
1611
    InsertionSet m_insertionSet;
1812
    InsertionSet m_insertionSet;
1813
    BlockInsertionSet m_blockInsertionSet;
1612
    BasicBlock* m_block { nullptr };
1814
    BasicBlock* m_block { nullptr };
1613
    unsigned m_index { 0 };
1815
    unsigned m_index { 0 };
1614
    Value* m_value { nullptr };
1816
    Value* m_value { nullptr };
- Source/JavaScriptCore/b3/B3StackSlotValue.cpp +5 lines
Lines 39-44 void StackSlotValue::dumpMeta(CommaPrint Source/JavaScriptCore/b3/B3StackSlotValue.cpp_sec1
39
    out.print(comma, "byteSize = ", m_byteSize, ", kind = ", m_kind);
39
    out.print(comma, "byteSize = ", m_byteSize, ", kind = ", m_kind);
40
}
40
}
41
41
42
Value* StackSlotValue::cloneImpl() const
43
{
44
    return new StackSlotValue(*this);
45
}
46
42
} } // namespace JSC::B3
47
} } // namespace JSC::B3
43
48
44
#endif // ENABLE(B3_JIT)
49
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3StackSlotValue.h +2 lines
Lines 59-64 public: Source/JavaScriptCore/b3/B3StackSlotValue.h_sec1
59
protected:
59
protected:
60
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
60
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
61
61
62
    Value* cloneImpl() const override;
63
62
private:
64
private:
63
    friend class Air::StackSlot;
65
    friend class Air::StackSlot;
64
    friend class Procedure;
66
    friend class Procedure;
- Source/JavaScriptCore/b3/B3SwitchValue.cpp +5 lines
Lines 63-68 void SwitchValue::dumpMeta(CommaPrinter& Source/JavaScriptCore/b3/B3SwitchValue.cpp_sec1
63
    out.print(comma, "fallThrough = ", fallThrough());
63
    out.print(comma, "fallThrough = ", fallThrough());
64
}
64
}
65
65
66
Value* SwitchValue::cloneImpl() const
67
{
68
    return new SwitchValue(*this);
69
}
70
66
SwitchValue::SwitchValue(
71
SwitchValue::SwitchValue(
67
    unsigned index, Origin origin, Value* child, const FrequentedBlock& fallThrough)
72
    unsigned index, Origin origin, Value* child, const FrequentedBlock& fallThrough)
68
    : ControlValue(index, Switch, Void, origin, child)
73
    : ControlValue(index, Switch, Void, origin, child)
- Source/JavaScriptCore/b3/B3SwitchValue.h +2 lines
Lines 116-121 public: Source/JavaScriptCore/b3/B3SwitchValue.h_sec1
116
protected:
116
protected:
117
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
117
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
118
118
119
    Value* cloneImpl() const override;
120
119
private:
121
private:
120
    friend class Procedure;
122
    friend class Procedure;
121
123
- Source/JavaScriptCore/b3/B3UpsilonValue.cpp +5 lines
Lines 45-50 void UpsilonValue::dumpMeta(CommaPrinter Source/JavaScriptCore/b3/B3UpsilonValue.cpp_sec1
45
    }
45
    }
46
}
46
}
47
47
48
Value* UpsilonValue::cloneImpl() const
49
{
50
    return new UpsilonValue(*this);
51
}
52
48
} } // namespace JSC::B3
53
} } // namespace JSC::B3
49
54
50
#endif // ENABLE(B3_JIT)
55
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/B3UpsilonValue.h -3 / +3 lines
Lines 49-54 public: Source/JavaScriptCore/b3/B3UpsilonValue.h_sec1
49
protected:
49
protected:
50
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
50
    void dumpMeta(CommaPrinter&, PrintStream&) const override;
51
51
52
    Value* cloneImpl() const override;
53
52
private:
54
private:
53
    friend class Procedure;
55
    friend class Procedure;
54
56
Lines 59-68 private: Source/JavaScriptCore/b3/B3UpsilonValue.h_sec2
59
        : Value(index, CheckedOpcode, Upsilon, Void, origin, value)
61
        : Value(index, CheckedOpcode, Upsilon, Void, origin, value)
60
        , m_phi(phi)
62
        , m_phi(phi)
61
    {
63
    {
62
        if (phi) {
64
        if (phi)
63
            ASSERT(value->type() == phi->type());
65
            ASSERT(value->type() == phi->type());
64
            ASSERT(phi->opcode() == Phi);
65
        }
66
    }
66
    }
67
67
68
    Value* m_phi;
68
    Value* m_phi;
- Source/JavaScriptCore/b3/B3Validate.cpp +1 lines
Lines 352-357 public: Source/JavaScriptCore/b3/B3Validate.cpp_sec1
352
            case Upsilon:
352
            case Upsilon:
353
                VALIDATE(value->numChildren() == 1, ("At ", *value));
353
                VALIDATE(value->numChildren() == 1, ("At ", *value));
354
                VALIDATE(value->as<UpsilonValue>()->phi(), ("At ", *value));
354
                VALIDATE(value->as<UpsilonValue>()->phi(), ("At ", *value));
355
                VALIDATE(value->as<UpsilonValue>()->phi()->opcode() == Phi, ("At ", *value));
355
                VALIDATE(value->child(0)->type() == value->as<UpsilonValue>()->phi()->type(), ("At ", *value));
356
                VALIDATE(value->child(0)->type() == value->as<UpsilonValue>()->phi()->type(), ("At ", *value));
356
                VALIDATE(valueInProc.contains(value->as<UpsilonValue>()->phi()), ("At ", *value));
357
                VALIDATE(valueInProc.contains(value->as<UpsilonValue>()->phi()), ("At ", *value));
357
                break;
358
                break;
- Source/JavaScriptCore/b3/B3Value.cpp -1 / +25 lines
Lines 89-106 void Value::replaceWithNop() Source/JavaScriptCore/b3/B3Value.cpp_sec1
89
    this->owner = owner;
89
    this->owner = owner;
90
}
90
}
91
91
92
void Value::replaceWithPhi()
93
{
94
    if (m_type == Void) {
95
        replaceWithNop();
96
        return;
97
    }
98
    
99
    unsigned index = m_index;
100
    Origin origin = m_origin;
101
    BasicBlock* owner = this->owner;
102
    Type type = m_type;
103
104
    this->Value::~Value();
105
106
    new (this) Value(index, Phi, type, origin);
107
108
    this->owner = owner;
109
}
110
92
void Value::dump(PrintStream& out) const
111
void Value::dump(PrintStream& out) const
93
{
112
{
94
    out.print(dumpPrefix, m_index);
113
    out.print(dumpPrefix, m_index);
95
}
114
}
96
115
116
Value* Value::cloneImpl() const
117
{
118
    return new Value(*this);
119
}
120
97
void Value::dumpChildren(CommaPrinter& comma, PrintStream& out) const
121
void Value::dumpChildren(CommaPrinter& comma, PrintStream& out) const
98
{
122
{
99
    for (Value* child : children())
123
    for (Value* child : children())
100
        out.print(comma, pointerDump(child));
124
        out.print(comma, pointerDump(child));
101
}
125
}
102
126
103
void Value::deepDump(const Procedure& proc, PrintStream& out) const
127
void Value::deepDump(const Procedure* proc, PrintStream& out) const
104
{
128
{
105
    out.print(m_type, " ", *this, " = ", m_opcode);
129
    out.print(m_type, " ", *this, " = ", m_opcode);
106
130
- Source/JavaScriptCore/b3/B3Value.h -6 / +29 lines
Lines 1-5 Source/JavaScriptCore/b3/B3Value.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2015 Apple Inc. All rights reserved.
2
 * Copyright (C) 2015-2016 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 42-51 namespace JSC { namespace B3 { Source/JavaScriptCore/b3/B3Value.h_sec2
42
42
43
class BasicBlock;
43
class BasicBlock;
44
class CheckValue;
44
class CheckValue;
45
class PhiChildren;
45
class Procedure;
46
class Procedure;
46
47
47
class JS_EXPORT_PRIVATE Value {
48
class JS_EXPORT_PRIVATE Value {
48
    WTF_MAKE_NONCOPYABLE(Value);
49
    WTF_MAKE_FAST_ALLOCATED;
49
    WTF_MAKE_FAST_ALLOCATED;
50
public:
50
public:
51
    typedef Vector<Value*, 3> AdjacencyList;
51
    typedef Vector<Value*, 3> AdjacencyList;
Lines 84-92 public: Source/JavaScriptCore/b3/B3Value.h_sec3
84
84
85
    void replaceWithIdentity(Value*);
85
    void replaceWithIdentity(Value*);
86
    void replaceWithNop();
86
    void replaceWithNop();
87
    void replaceWithPhi();
87
88
88
    void dump(PrintStream&) const;
89
    void dump(PrintStream&) const;
89
    void deepDump(const Procedure&, PrintStream&) const;
90
    void deepDump(const Procedure*, PrintStream&) const;
90
91
91
    // This is how you cast Values. For example, if you want to do something provided that we have a
92
    // This is how you cast Values. For example, if you want to do something provided that we have a
92
    // ArgumentRegValue, you can do:
93
    // ArgumentRegValue, you can do:
Lines 204-210 public: Source/JavaScriptCore/b3/B3Value.h_sec4
204
    // of Identity's.
205
    // of Identity's.
205
    void performSubstitution();
206
    void performSubstitution();
206
207
208
    // Walk the ancestors of this value (i.e. the graph of things it transitively uses). This
209
    // either walks phis or not, depending on whether PhiChildren is null. Your callback gets
210
    // called with the signature:
211
    //
212
    //     (Value*) -> WalkStatus
213
    enum WalkStatus {
214
        Continue,
215
        IgnoreChildren,
216
        Stop
217
    };
218
    template<typename Functor>
219
    void walk(const Functor& functor, PhiChildren* = nullptr);
220
207
protected:
221
protected:
222
    virtual Value* cloneImpl() const;
223
    
208
    virtual void dumpChildren(CommaPrinter&, PrintStream&) const;
224
    virtual void dumpChildren(CommaPrinter&, PrintStream&) const;
209
    virtual void dumpMeta(CommaPrinter&, PrintStream&) const;
225
    virtual void dumpMeta(CommaPrinter&, PrintStream&) const;
210
226
Lines 220-225 private: Source/JavaScriptCore/b3/B3Value.h_sec5
220
236
221
protected:
237
protected:
222
    enum CheckedOpcodeTag { CheckedOpcode };
238
    enum CheckedOpcodeTag { CheckedOpcode };
239
240
    Value(const Value&) = default;
241
    Value& operator=(const Value&) = default;
223
    
242
    
224
    // Instantiate values via Procedure.
243
    // Instantiate values via Procedure.
225
    // This form requires specifying the type explicitly:
244
    // This form requires specifying the type explicitly:
Lines 315-321 public: Source/JavaScriptCore/b3/B3Value.h_sec6
315
334
316
class DeepValueDump {
335
class DeepValueDump {
317
public:
336
public:
318
    DeepValueDump(const Procedure& proc, const Value* value)
337
    DeepValueDump(const Procedure* proc, const Value* value)
319
        : m_proc(proc)
338
        : m_proc(proc)
320
        , m_value(value)
339
        , m_value(value)
321
    {
340
    {
Lines 330-342 public: Source/JavaScriptCore/b3/B3Value.h_sec7
330
    }
349
    }
331
350
332
private:
351
private:
333
    const Procedure& m_proc;
352
    const Procedure* m_proc;
334
    const Value* m_value;
353
    const Value* m_value;
335
};
354
};
336
355
337
inline DeepValueDump deepDump(const Procedure& proc, const Value* value)
356
inline DeepValueDump deepDump(const Procedure& proc, const Value* value)
338
{
357
{
339
    return DeepValueDump(proc, value);
358
    return DeepValueDump(&proc, value);
359
}
360
inline DeepValueDump deepDump(const Value* value)
361
{
362
    return DeepValueDump(nullptr, value);
340
}
363
}
341
364
342
} } // namespace JSC::B3
365
} } // namespace JSC::B3
- Source/JavaScriptCore/b3/B3ValueInlines.h +25 lines
Lines 34-41 Source/JavaScriptCore/b3/B3ValueInlines.h_sec1
34
#include "B3ConstDoubleValue.h"
34
#include "B3ConstDoubleValue.h"
35
#include "B3ConstFloatValue.h"
35
#include "B3ConstFloatValue.h"
36
#include "B3PatchpointValue.h"
36
#include "B3PatchpointValue.h"
37
#include "B3PhiChildren.h"
37
#include "B3Procedure.h"
38
#include "B3Procedure.h"
38
#include "B3Value.h"
39
#include "B3Value.h"
40
#include <wtf/GraphNodeWorklist.h>
39
41
40
namespace JSC { namespace B3 {
42
namespace JSC { namespace B3 {
41
43
Lines 204-209 inline T Value::asNumber() const Source/JavaScriptCore/b3/B3ValueInlines.h_sec2
204
    }
206
    }
205
}
207
}
206
208
209
template<typename Functor>
210
void Value::walk(const Functor& functor, PhiChildren* phiChildren)
211
{
212
    GraphNodeWorklist<Value*> worklist;
213
    worklist.push(this);
214
    while (Value* value = worklist.pop()) {
215
        WalkStatus status = functor(value);
216
        switch (status) {
217
        case Continue:
218
            if (value->opcode() == Phi) {
219
                if (phiChildren)
220
                    worklist.pushAll(phiChildren->at(value).values());
221
            } else
222
                worklist.pushAll(value->children());
223
            break;
224
        case IgnoreChildren:
225
            break;
226
        case Stop:
227
            return;
228
        }
229
    }
230
}
231
207
} } // namespace JSC::B3
232
} } // namespace JSC::B3
208
233
209
#endif // ENABLE(B3_JIT)
234
#endif // ENABLE(B3_JIT)
- Source/JavaScriptCore/b3/testb3.cpp +119 lines
Lines 9065-9070 void testSelectInvert() Source/JavaScriptCore/b3/testb3.cpp_sec1
9065
    CHECK(invoke<intptr_t>(*code, 43, 642462, 32533) == 32533);
9065
    CHECK(invoke<intptr_t>(*code, 43, 642462, 32533) == 32533);
9066
}
9066
}
9067
9067
9068
void testCheckSelect()
9069
{
9070
    Procedure proc;
9071
    BasicBlock* root = proc.addBlock();
9072
9073
    CheckValue* check = root->appendNew<CheckValue>(
9074
        proc, Check, Origin(),
9075
        root->appendNew<Value>(
9076
            proc, Add, Origin(),
9077
            root->appendNew<Value>(
9078
                proc, Select, Origin(),
9079
                root->appendNew<Value>(
9080
                    proc, BitAnd, Origin(),
9081
                    root->appendNew<Value>(
9082
                        proc, Trunc, Origin(),
9083
                        root->appendNew<ArgumentRegValue>(
9084
                            proc, Origin(), GPRInfo::argumentGPR0)),
9085
                    root->appendNew<Const32Value>(proc, Origin(), 0xff)),
9086
                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
9087
                root->appendNew<ConstPtrValue>(proc, Origin(), 35)),
9088
            root->appendNew<ConstPtrValue>(proc, Origin(), 42)));
9089
    unsigned generationCount = 0;
9090
    check->setGenerator(
9091
        [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
9092
            AllowMacroScratchRegisterUsage allowScratch(jit);
9093
9094
            generationCount++;
9095
            jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
9096
            jit.emitFunctionEpilogue();
9097
            jit.ret();
9098
        });
9099
    
9100
    root->appendNew<ControlValue>(
9101
        proc, Return, Origin(),
9102
        root->appendNew<Const32Value>(proc, Origin(), 0));
9103
9104
    auto code = compile(proc);
9105
    CHECK(generationCount == 2);
9106
    CHECK(invoke<int>(*code, true, static_cast<intptr_t>(-42)) == 0);
9107
    CHECK(invoke<int>(*code, false, static_cast<intptr_t>(5555)) == 666);
9108
    CHECK(invoke<int>(*code, true, static_cast<intptr_t>(0)) == 666);
9109
}
9110
9111
void testCheckSelectCheckSelect()
9112
{
9113
    Procedure proc;
9114
    BasicBlock* root = proc.addBlock();
9115
9116
    CheckValue* check = root->appendNew<CheckValue>(
9117
        proc, Check, Origin(),
9118
        root->appendNew<Value>(
9119
            proc, Add, Origin(),
9120
            root->appendNew<Value>(
9121
                proc, Select, Origin(),
9122
                root->appendNew<Value>(
9123
                    proc, BitAnd, Origin(),
9124
                    root->appendNew<Value>(
9125
                        proc, Trunc, Origin(),
9126
                        root->appendNew<ArgumentRegValue>(
9127
                            proc, Origin(), GPRInfo::argumentGPR0)),
9128
                    root->appendNew<Const32Value>(proc, Origin(), 0xff)),
9129
                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
9130
                root->appendNew<ConstPtrValue>(proc, Origin(), 35)),
9131
            root->appendNew<ConstPtrValue>(proc, Origin(), 42)));
9132
9133
    unsigned generationCount = 0;
9134
    check->setGenerator(
9135
        [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
9136
            AllowMacroScratchRegisterUsage allowScratch(jit);
9137
9138
            generationCount++;
9139
            jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
9140
            jit.emitFunctionEpilogue();
9141
            jit.ret();
9142
        });
9143
    
9144
    CheckValue* check2 = root->appendNew<CheckValue>(
9145
        proc, Check, Origin(),
9146
        root->appendNew<Value>(
9147
            proc, Add, Origin(),
9148
            root->appendNew<Value>(
9149
                proc, Select, Origin(),
9150
                root->appendNew<Value>(
9151
                    proc, BitAnd, Origin(),
9152
                    root->appendNew<Value>(
9153
                        proc, Trunc, Origin(),
9154
                        root->appendNew<ArgumentRegValue>(
9155
                            proc, Origin(), GPRInfo::argumentGPR2)),
9156
                    root->appendNew<Const32Value>(proc, Origin(), 0xff)),
9157
                root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3),
9158
                root->appendNew<ConstPtrValue>(proc, Origin(), 36)),
9159
            root->appendNew<ConstPtrValue>(proc, Origin(), 43)));
9160
9161
    unsigned generationCount2 = 0;
9162
    check2->setGenerator(
9163
        [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
9164
            AllowMacroScratchRegisterUsage allowScratch(jit);
9165
9166
            generationCount2++;
9167
            jit.move(CCallHelpers::TrustedImm32(667), GPRInfo::returnValueGPR);
9168
            jit.emitFunctionEpilogue();
9169
            jit.ret();
9170
        });
9171
    
9172
    root->appendNew<ControlValue>(
9173
        proc, Return, Origin(),
9174
        root->appendNew<Const32Value>(proc, Origin(), 0));
9175
9176
    auto code = compile(proc);
9177
    CHECK(generationCount == 2);
9178
    CHECK(invoke<int>(*code, true, static_cast<intptr_t>(-42), true, static_cast<intptr_t>(-43)) == 0);
9179
    CHECK(invoke<int>(*code, false, static_cast<intptr_t>(5555), true, static_cast<intptr_t>(-43)) == 666);
9180
    CHECK(invoke<int>(*code, true, static_cast<intptr_t>(0), true, static_cast<intptr_t>(-43)) == 666);
9181
    CHECK(invoke<int>(*code, true, static_cast<intptr_t>(-42), false, static_cast<intptr_t>(5555)) == 667);
9182
    CHECK(invoke<int>(*code, true, static_cast<intptr_t>(-42), true, static_cast<intptr_t>(0)) == 667);
9183
}
9184
9068
void testPowDoubleByIntegerLoop(double xOperand, int32_t yOperand)
9185
void testPowDoubleByIntegerLoop(double xOperand, int32_t yOperand)
9069
{
9186
{
9070
    Procedure proc;
9187
    Procedure proc;
Lines 10524-10529 void run(const char* filter) Source/JavaScriptCore/b3/testb3.cpp_sec2
10524
    RUN(testSelectFold(42));
10641
    RUN(testSelectFold(42));
10525
    RUN(testSelectFold(43));
10642
    RUN(testSelectFold(43));
10526
    RUN(testSelectInvert());
10643
    RUN(testSelectInvert());
10644
    RUN(testCheckSelect());
10645
    RUN(testCheckSelectCheckSelect());
10527
    RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands<double>(), int64Operands());
10646
    RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands<double>(), int64Operands());
10528
10647
10529
    RUN(testTruncOrHigh());
10648
    RUN(testTruncOrHigh());
- Source/JavaScriptCore/dfg/DFGCommon.h -1 / +1 lines
Lines 38-44 namespace JSC { namespace DFG { Source/JavaScriptCore/dfg/DFGCommon.h_sec1
38
// We are in the middle of an experimental transition from LLVM to B3 as the backend for the FTL. We don't
38
// We are in the middle of an experimental transition from LLVM to B3 as the backend for the FTL. We don't
39
// yet know how it will turn out. For now, this flag will control whether FTL uses B3. Remember to set this
39
// yet know how it will turn out. For now, this flag will control whether FTL uses B3. Remember to set this
40
// to 0 before committing!
40
// to 0 before committing!
41
#define FTL_USES_B3 0
41
#define FTL_USES_B3 1
42
42
43
struct Node;
43
struct Node;
44
44
- Source/WTF/wtf/GraphNodeWorklist.h +7 lines
Lines 45-50 public: Source/WTF/wtf/GraphNodeWorklist.h_sec1
45
        return true;
45
        return true;
46
    }
46
    }
47
47
48
    template<typename Iterable>
49
    void pushAll(const Iterable& iterable)
50
    {
51
        for (Node node : iterable)
52
            push(node);
53
    }
54
48
    bool isEmpty() const { return m_stack.isEmpty(); }
55
    bool isEmpty() const { return m_stack.isEmpty(); }
49
    bool notEmpty() const { return !m_stack.isEmpty(); }
56
    bool notEmpty() const { return !m_stack.isEmpty(); }
50
    
57
    

Return to Bug 153200