Changeset 127503 in webkit


Ignore:
Timestamp:
Sep 4, 2012 2:15:02 PM (12 years ago)
Author:
fpizlo@apple.com
Message:

DFG GetByVal for JSArrays shouldn't OSR exit every time that the index is out of bound
https://bugs.webkit.org/show_bug.cgi?id=95717

Reviewed by Oliver Hunt.

Make GetByVal for JSArrayOutOfBounds do meaningful things. The profiling was already
there so we should just use it!

  • bytecode/DFGExitProfile.h:

(JSC::DFG::exitKindToString):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r127484 r127503  
     12012-09-04  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG GetByVal for JSArrays shouldn't OSR exit every time that the index is out of bound
     4        https://bugs.webkit.org/show_bug.cgi?id=95717
     5
     6        Reviewed by Oliver Hunt.
     7
     8        Make GetByVal for JSArrayOutOfBounds do meaningful things. The profiling was already
     9        there so we should just use it!
     10
     11        * bytecode/DFGExitProfile.h:
     12        (JSC::DFG::exitKindToString):
     13        * dfg/DFGAbstractState.cpp:
     14        (JSC::DFG::AbstractState::execute):
     15        * dfg/DFGOperations.cpp:
     16        * dfg/DFGOperations.h:
     17        * dfg/DFGSpeculativeJIT.h:
     18        (JSC::DFG::SpeculativeJIT::callOperation):
     19        * dfg/DFGSpeculativeJIT32_64.cpp:
     20        (JSC::DFG::SpeculativeJIT::compile):
     21        * dfg/DFGSpeculativeJIT64.cpp:
     22        (JSC::DFG::SpeculativeJIT::compile):
     23
    1242012-09-04  Zoltan Horvath  <zoltan@webkit.org>
    225
  • trunk/Source/JavaScriptCore/bytecode/DFGExitProfile.h

    r124398 r127503  
    5959    case NegativeZero:
    6060        return "NegativeZero";
     61    case OutOfBounds:
     62        return "OutOfBounds";
    6163    case InadequateCoverage:
    6264        return "InadequateCoverage";
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r127479 r127503  
    854854            break;
    855855        case Array::JSArray:
     856            forNode(node.child2()).filter(SpecInt32);
     857            forNode(nodeIndex).makeTop();
     858            break;
    856859        case Array::JSArrayOutOfBounds:
    857             // FIXME: We should have more conservative handling of the out-of-bounds
    858             // case.
    859860            forNode(node.child2()).filter(SpecInt32);
     861            clobberWorld(node.codeOrigin, indexInBlock);
    860862            forNode(nodeIndex).makeTop();
    861863            break;
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r127202 r127503  
    408408    Identifier ident(exec, property.toString(exec)->value(exec));
    409409    return JSValue::encode(JSValue(base).get(exec, ident));
     410}
     411
     412EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
     413{
     414    JSGlobalData* globalData = &exec->globalData();
     415    NativeCallFrameTracer tracer(globalData, exec);
     416
     417    // Use this since we know that the value is out of bounds.
     418    return JSValue::encode(JSValue(base).get(exec, index));
    410419}
    411420
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r126494 r127503  
    6363typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_E)(ExecState*);
    6464typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EA)(ExecState*, JSArray*);
     65typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EAZ)(ExecState*, JSArray*, int32_t);
    6566typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*);
    6667typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECI)(ExecState*, JSCell*, Identifier*);
     
    117118EncodedJSValue DFG_OPERATION operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty) WTF_INTERNAL;
    118119EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState*, JSCell*, EncodedJSValue encodedProperty) WTF_INTERNAL;
     120EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState*, JSArray*, int32_t) WTF_INTERNAL;
    119121EncodedJSValue DFG_OPERATION operationGetById(ExecState*, EncodedJSValue, Identifier*) WTF_INTERNAL;
    120122EncodedJSValue DFG_OPERATION operationGetByIdBuildList(ExecState*, EncodedJSValue, Identifier*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r127479 r127503  
    11991199        return appendCallWithExceptionCheckSetResult(operation, result);
    12001200    }
     1201    JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1202    {
     1203        m_jit.setupArgumentsWithExecState(arg1, arg2);
     1204        return appendCallWithExceptionCheckSetResult(operation, result);
     1205    }
    12011206    JITCompiler::Call callOperation(J_DFGOperation_ESt operation, GPRReg result, Structure* structure)
    12021207    {
     
    14801485    {
    14811486        m_jit.setupArgumentsWithExecState(arg1);
     1487        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
     1488    }
     1489    JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
     1490    {
     1491        m_jit.setupArgumentsWithExecState(arg1, arg2);
    14821492        return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
    14831493    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r127479 r127503  
    25552555            break;
    25562556        }
    2557         case Array::JSArray:
    2558         case Array::JSArrayOutOfBounds: {
     2557        case Array::JSArray: {
    25592558            SpeculateStrictInt32Operand property(this, node.child2());
    25602559            StorageOperand storage(this, node.child3());
     
    25712570                GPRReg baseReg = base.gpr();
    25722571                // We've already speculated that it's some kind of array, at this point.
    2573                 speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
     2572                speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
    25742573            }
    25752574
     
    25782577
    25792578            m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
    2580             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
     2579            speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
    25812580            m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
    2582 
     2581           
    25832582            jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
     2583            break;
     2584        }
     2585        case Array::JSArrayOutOfBounds: {
     2586            SpeculateCellOperand base(this, node.child1());
     2587            SpeculateStrictInt32Operand property(this, node.child2());
     2588            StorageOperand storage(this, node.child3());
     2589            GPRReg propertyReg = property.gpr();
     2590            GPRReg storageReg = storage.gpr();
     2591
     2592            if (!m_compileOkay)
     2593                return;
     2594
     2595            GPRTemporary resultTag(this);
     2596            GPRTemporary resultPayload(this);
     2597            GPRReg resultTagReg = resultTag.gpr();
     2598            GPRReg resultPayloadReg = resultPayload.gpr();
     2599
     2600            // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
     2601            // If we have predicted the base to be type array, we can skip the check.
     2602            GPRReg baseReg = base.gpr();
     2603            // We've already speculated that it's some kind of array, at this point.
     2604            JITCompiler::Jump outOfBounds = m_jit.branch32(
     2605                MacroAssembler::AboveOrEqual, propertyReg,
     2606                MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
     2607
     2608            m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg);
     2609            JITCompiler::Jump hole = m_jit.branch32(
     2610                MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag));
     2611            m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg);
     2612           
     2613            JITCompiler::JumpList slowCases;
     2614            slowCases.append(outOfBounds);
     2615            slowCases.append(hole);
     2616            addSlowPathGenerator(
     2617                slowPathCall(
     2618                    slowCases, this, operationGetByValArrayInt,
     2619                    JSValueRegs(resultTagReg, resultPayloadReg),
     2620                    baseReg, propertyReg));
     2621
     2622            jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex);
    25842623            break;
    25852624        }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r127479 r127503  
    26012601            // at this point.
    26022602           
    2603             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
     2603            MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
     2604            if (node.arrayMode() == Array::JSArray)
     2605                speculationCheck(OutOfBounds, JSValueRegs(), NoNode, outOfBounds);
    26042606           
    26052607            GPRTemporary result(this);
    26062608            m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
    2607             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()));
     2609            MacroAssembler::Jump hole = m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr());
     2610            if (node.arrayMode() == Array::JSArray)
     2611                speculationCheck(OutOfBounds, JSValueRegs(), NoNode, hole);
     2612            else {
     2613                MacroAssembler::JumpList slowCases;
     2614                slowCases.append(outOfBounds);
     2615                slowCases.append(hole);
     2616                addSlowPathGenerator(
     2617                    slowPathCall(
     2618                        slowCases, this, operationGetByValArrayInt,
     2619                        result.gpr(), baseReg, propertyReg));
     2620            }
    26082621           
    26092622            jsValueResult(result.gpr(), m_compileIndex);
Note: See TracChangeset for help on using the changeset viewer.