| Differences between
and this patch
- Source/JavaScriptCore/ChangeLog +33 lines
Lines 1-3 Source/JavaScriptCore/ChangeLog_sec1
1
2016-01-04  Filip Pizlo  <fpizlo@apple.com>
2
3
        FTL B3 should do the ArithSub binary snippet
4
        https://bugs.webkit.org/show_bug.cgi?id=152705
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        This implements the ArithSub binary snippet generator in FTL B3.
9
10
        While doing this, I discovered that the DFG type inference logic for ArithSub contains a
11
        classic mistake: it causes the snippets to kick in when the type set does not contain numbers
12
        rather than kicking in when the type set contains non-numbers. So, the original test that I
13
        wrote for this doesn't work right (it runs to completion but OSR exits ad infinitum). I wrote
14
        a second test that is simpler, and that one shows that the binary snippets "work". That's
15
        sort of a joke though, since the only way to trigger binary snippets is to never pass numbers
16
        and the only way to actually cause a binary snippet to do meaninful work is to pass numbers.
17
        I filed a bug about this mess: https://bugs.webkit.org/show_bug.cgi?id=152708.
18
19
        * ftl/FTLLowerDFGToLLVM.cpp:
20
        (JSC::FTL::DFG::LowerDFGToLLVM::compileUntypedBinaryOp):
21
        (JSC::FTL::DFG::LowerDFGToLLVM::compileArithAddOrSub):
22
        (JSC::FTL::DFG::LowerDFGToLLVM::nonSpeculativeCompare):
23
        (JSC::FTL::DFG::LowerDFGToLLVM::emitBinarySnippet):
24
        (JSC::FTL::DFG::LowerDFGToLLVM::allocateCell):
25
        (JSC::FTL::DFG::LowerDFGToLLVM::lowBlock):
26
        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitDescriptor):
27
        * tests/stress/object-sub.js: Added.
28
        (foo):
29
        (things.valueOf):
30
        * tests/stress/untyped-sub.js: Added.
31
        (foo):
32
        (valueOf):
33
1
2016-01-04  Filip Pizlo  <fpizlo@apple.com>
34
2016-01-04  Filip Pizlo  <fpizlo@apple.com>
2
35
3
        Unreviewed, disable FTL B3 for now. I didn't intend to enable it yet.
36
        Unreviewed, disable FTL B3 for now. I didn't intend to enable it yet.
- 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/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp -7 / +71 lines
Lines 1-5 Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
2
 * Copyright (C) 2013-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 51-56 Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec2
51
#include "FTLOutput.h"
51
#include "FTLOutput.h"
52
#include "FTLThunks.h"
52
#include "FTLThunks.h"
53
#include "FTLWeightedTarget.h"
53
#include "FTLWeightedTarget.h"
54
#include "JITSubGenerator.h"
54
#include "JSArrowFunction.h"
55
#include "JSArrowFunction.h"
55
#include "JSCInlines.h"
56
#include "JSCInlines.h"
56
#include "JSGeneratorFunction.h"
57
#include "JSGeneratorFunction.h"
Lines 1087-1106 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec3
1087
1088
1088
        if (constInt32Opt == HasConstInt32OperandOptimization && leftChild->isInt32Constant())
1089
        if (constInt32Opt == HasConstInt32OperandOptimization && leftChild->isInt32Constant())
1089
            leftOperand.setConstInt32(leftChild->asInt32());
1090
            leftOperand.setConstInt32(leftChild->asInt32());
1090
#if USE(JSVALUE64)
1091
        else if (constDoubleOpt == HasConstDoubleOperandOptimization && leftChild->isDoubleConstant())
1091
        else if (constDoubleOpt == HasConstDoubleOperandOptimization && leftChild->isDoubleConstant())
1092
            leftOperand.setConstDouble(leftChild->asNumber());
1092
            leftOperand.setConstDouble(leftChild->asNumber());
1093
#endif
1094
1093
1095
        if (leftOperand.isConst()) {
1094
        if (leftOperand.isConst()) {
1096
            // Because the snippet does not support both operands being constant, if the left
1095
            // Because the snippet does not support both operands being constant, if the left
1097
            // operand is already a constant, we'll just pretend the right operand is not.
1096
            // operand is already a constant, we'll just pretend the right operand is not.
1098
        } else if (constInt32Opt == HasConstInt32OperandOptimization && rightChild->isInt32Constant())
1097
        } else if (constInt32Opt == HasConstInt32OperandOptimization && rightChild->isInt32Constant())
1099
            rightOperand.setConstInt32(rightChild->asInt32());
1098
            rightOperand.setConstInt32(rightChild->asInt32());
1100
#if USE(JSVALUE64)
1101
        else if (constDoubleOpt == HasConstDoubleOperandOptimization && rightChild->isDoubleConstant())
1099
        else if (constDoubleOpt == HasConstDoubleOperandOptimization && rightChild->isDoubleConstant())
1102
            rightOperand.setConstDouble(rightChild->asNumber());
1100
            rightOperand.setConstDouble(rightChild->asNumber());
1103
#endif
1104
1101
1105
        RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
1102
        RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
1106
1103
Lines 1747-1754 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec4
1747
                DFG_CRASH(m_graph, m_node, "Bad use kind");
1744
                DFG_CRASH(m_graph, m_node, "Bad use kind");
1748
                break;
1745
                break;
1749
            }
1746
            }
1750
            
1747
1748
#if FTL_USES_B3
1749
            emitBinarySnippet<JITSubGenerator>(operationValueSub);
1750
#else // FTL_USES_B3
1751
            compileUntypedBinaryOp<ArithSubDescriptor, DoesNotHaveConstInt32OperandOptimization, DoesNotHaveConstDoubleOperandOptimization>();
1751
            compileUntypedBinaryOp<ArithSubDescriptor, DoesNotHaveConstInt32OperandOptimization, DoesNotHaveConstDoubleOperandOptimization>();
1752
#endif // FTL_USES_B3
1752
            break;
1753
            break;
1753
        }
1754
        }
1754
1755
Lines 7375-7380 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec5
7375
        setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
7376
        setBoolean(m_out.phi(m_out.boolean, fastResult, slowResult));
7376
    }
7377
    }
7377
7378
7379
#if FTL_USES_B3
7380
    enum ScratchFPRUsage {
7381
        DontNeedScratchFPR,
7382
        NeedScratchFPR
7383
    };
7384
    template<typename BinaryArithOpGenerator, ScratchFPRUsage scratchFPRUsage = DontNeedScratchFPR>
7385
    void emitBinarySnippet(J_JITOperation_EJJ slowPathFunction)
7386
    {
7387
        Node* node = m_node;
7388
        
7389
        // FIXME: Make this do exceptions.
7390
        // https://bugs.webkit.org/show_bug.cgi?id=151686
7391
            
7392
        LValue left = lowJSValue(node->child1());
7393
        LValue right = lowJSValue(node->child2());
7394
7395
        SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
7396
        SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
7397
            
7398
        PatchpointValue* patchpoint = m_out.patchpoint(Int64);
7399
        patchpoint->append(left, ValueRep::SomeRegister);
7400
        patchpoint->append(right, ValueRep::SomeRegister);
7401
        patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
7402
        patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
7403
        patchpoint->numGPScratchRegisters = 1;
7404
        patchpoint->numFPScratchRegisters = 2;
7405
        if (scratchFPRUsage == NeedScratchFPR)
7406
            patchpoint->numFPScratchRegisters++;
7407
        patchpoint->clobber(RegisterSet::macroScratchRegisters());
7408
        State* state = &m_ftlState;
7409
        patchpoint->setGenerator(
7410
            [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
7411
                AllowMacroScratchRegisterUsage allowScratch(jit);
7412
                    
7413
                auto generator = Box<BinaryArithOpGenerator>::create(
7414
                    leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
7415
                    JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()),
7416
                    params.fpScratch(0), params.fpScratch(1), params.gpScratch(0),
7417
                    scratchFPRUsage == NeedScratchFPR ? params.fpScratch(2) : InvalidFPRReg);
7418
7419
                generator->generateFastPath(jit);
7420
                generator->endJumpList().link(&jit);
7421
                CCallHelpers::Label done = jit.label();
7422
7423
                params.addLatePath(
7424
                    [=] (CCallHelpers& jit) {
7425
                        AllowMacroScratchRegisterUsage allowScratch(jit);
7426
                            
7427
                        // FIXME: Make this do something.
7428
                        CCallHelpers::JumpList exceptions;
7429
7430
                        generator->slowPathJumpList().link(&jit);
7431
                        callOperation(
7432
                            *state, params.unavailableRegisters(), jit, node->origin.semantic,
7433
                            &exceptions, slowPathFunction, params[0].gpr(), params[1].gpr(),
7434
                            params[2].gpr());
7435
                        jit.jump().linkTo(done, &jit);
7436
                    });
7437
            });
7438
7439
        setJSValue(patchpoint);
7440
    }
7441
#endif // FTL_USES_B3
7442
7378
    LValue allocateCell(LValue allocator, LBasicBlock slowPath)
7443
    LValue allocateCell(LValue allocator, LBasicBlock slowPath)
7379
    {
7444
    {
7380
        LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
7445
        LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
Lines 9860-9866 private: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp_sec6
9860
        return m_blocks.get(block);
9925
        return m_blocks.get(block);
9861
    }
9926
    }
9862
9927
9863
9864
#if FTL_USES_B3
9928
#if FTL_USES_B3
9865
    OSRExitDescriptor* appendOSRExitDescriptor(FormattedValue lowValue, Node* highValue)
9929
    OSRExitDescriptor* appendOSRExitDescriptor(FormattedValue lowValue, Node* highValue)
9866
    {
9930
    {
- Source/JavaScriptCore/tests/stress/object-sub.js +16 lines
Line 0 Source/JavaScriptCore/tests/stress/object-sub.js_sec1
1
function foo(a, b) {
2
    return a - b;
3
}
4
5
noInline(foo);
6
7
var things = [{valueOf: function() { return 4; }}];
8
var results = [3];
9
10
for (var i = 0; i < 100000; ++i) {
11
    var result = foo(things[i % things.length], 1);
12
    var expected = results[i % results.length];
13
    if (result != expected)
14
        throw "Error: bad result for i = " + i + ": " + result;
15
}
16
- Source/JavaScriptCore/tests/stress/untyped-sub.js +16 lines
Line 0 Source/JavaScriptCore/tests/stress/untyped-sub.js_sec1
1
function foo(a, b) {
2
    return a - b;
3
}
4
5
noInline(foo);
6
7
var things = [1, 2.5, "3", {valueOf: function() { return 4; }}];
8
var results = [0, 1.5, 2, 3];
9
10
for (var i = 0; i < 100000; ++i) {
11
    var result = foo(things[i % things.length], 1);
12
    var expected = results[i % results.length];
13
    if (result != expected)
14
        throw "Error: bad result for i = " + i + ": " + result;
15
}
16

Return to Bug 152705