Changeset 185240 in webkit


Ignore:
Timestamp:
Jun 4, 2015 10:20:45 PM (9 years ago)
Author:
benjamin@webkit.org
Message:

[JSC] Always track out-of-bounds array access explicitly instead of relying on the slow case
https://bugs.webkit.org/show_bug.cgi?id=145673

Patch by Benjamin Poulain <bpoulain@apple.com> on 2015-06-04
Reviewed by Geoffrey Garen.

Previously, we were deciding to use out-of-bounds speculation based on two informations:
-Explicitly detected out-of-bounds accesses tracked on ArrayProfile.
-The number of time we took the slow cases in the baseline JIT.

The heuristic based on slow cases was a little too fragile.

In some cases, we were running into that limit just because the indexing type changes between
two values (typically Int32Array and DoubleArray). Sometimes we were just unlucky on what
we used for the inline cache.

In Kraken, this was hurting us on "audio-beat-detection" and "audio-fft". The array types we see
change between Int32 and Double. We run into the slow path a bit but never hit
out-of-bounds.

By the time we compile in DFG, we have stable Double Arrays but we speculate out-of-bounds based
on the number of slow cases we took. Because of that, we start boxing the double on GetByVal,
using DoubleRep, etc. adding a ton of overhead over otherwise very simple operations.

WebXPRT was also suffering from this problem but the other way arround: we were missing
the out-of-bounds accesses due to changes in indexing types, we were below the threshold
of slow-path access, thus we predicted in-bounds accesses for code that was doing plenty
of out-of-bands.

This patch fixes the problem by tracking the out-of-bounds access explicitly any time we go
into the slow path in baseline JIT. Since we no longer miss any out-of-bounds, we can remove
the slow-path heuristic.

There is new additional special case in the C code regarding out-of-bounds: Arguments access.
Mispredicting out-of-bounds accesses on arguments is a disaster for performance, so those are
tracked in the way DFG expect it.

There are a few important cases that are still not covered optimally:
-PutByVal on Arguments.
-Get/Put ByVal on TypedArray.
Those are simply not used by DFG in any way. TypedArrays should probably be looked at in the future.

  • bytecode/ArrayProfile.cpp:

(JSC::ArrayProfile::computeUpdatedPrediction):
The inline-cache repatch cases now update the ArrayProfile information. This has no value in baseline
JIT but it helps avoiding one recompile in DFG for the missing ArrayProfile information.

  • bytecode/ArrayProfile.h:

(JSC::ArrayProfile::setOutOfBounds):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::getArrayMode):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::getArrayModeConsideringSlowPath): Deleted.

  • jit/CCallHelpers.h:

(JSC::CCallHelpers::setupArgumentsWithExecState):

  • jit/JIT.h:
  • jit/JITInlines.h:

(JSC::JIT::callOperation):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emitSlow_op_has_indexed_property):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emitSlow_op_has_indexed_property):

  • jit/JITOperations.cpp:

(JSC::canUseFastArgumentAccess):
This is not my favorite part of this patch.

I tried having JSObject::canGetIndexQuickly() handle arguments which would put everything
on the generic path. Unfortunately, that code is very performance sensitive and some benchmarks were
impacted by over 10%

I left JSObject::canGetIndexQuickly() alone, and I added the canUseFastArgumentAccess() mirroring
how DFG uses out-of-bounds for Arguments.

(JSC::getByVal):

  • jit/JITOperations.h:
  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emitSlow_op_put_by_val):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emitSlow_op_put_by_val):

  • runtime/JSPromiseFunctions.cpp:
  • tests/stress/get-by-val-out-of-bounds-basics.js: Added.

(opaqueGetByValOnInt32ArrayEarlyOutOfBounds):
(testInt32ArrayEarlyOutOfBounds):
(testIndexingTypeChangesOnInt32Array):
(opaqueGetByValOnStringArrayHotOutOfBounds):
(testStringArrayHotOutOfBounds):
(testIndexingTypeChangesOnStringArray):
(opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds):
(testStringAndInt32ArrayHotOutOfBounds):
(opaqueGetByValOnDoubleArrayHotOutOfBounds):

  • tests/stress/put-by-val-out-of-bounds-basics.js: Added.

(opaquePutByValOnInt32ArrayEarlyOutOfBounds):
(testInt32ArrayEarlyOutOfBounds):
(opaquePutByValOnStringArrayHotOutOfBounds):
(testStringArrayHotOutOfBounds):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r185239 r185240  
     12015-06-04  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] Always track out-of-bounds array access explicitly instead of relying on the slow case
     4        https://bugs.webkit.org/show_bug.cgi?id=145673
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Previously, we were deciding to use out-of-bounds speculation based on two informations:
     9        -Explicitly detected out-of-bounds accesses tracked on ArrayProfile.
     10        -The number of time we took the slow cases in the baseline JIT.
     11
     12        The heuristic based on slow cases was a little too fragile.
     13
     14        In some cases, we were running into that limit just because the indexing type changes between
     15        two values (typically Int32Array and DoubleArray). Sometimes we were just unlucky on what
     16        we used for the inline cache.
     17
     18        In Kraken, this was hurting us on "audio-beat-detection" and "audio-fft". The array types we see
     19        change between Int32 and Double. We run into the slow path a bit but never hit
     20        out-of-bounds.
     21
     22        By the time we compile in DFG, we have stable Double Arrays but we speculate out-of-bounds based
     23        on the number of slow cases we took. Because of that, we start boxing the double on GetByVal,
     24        using DoubleRep, etc. adding a ton of overhead over otherwise very simple operations.
     25
     26        WebXPRT was also suffering from this problem but the other way arround: we were missing
     27        the out-of-bounds accesses due to changes in indexing types, we were below the threshold
     28        of slow-path access, thus we predicted in-bounds accesses for code that was doing plenty
     29        of out-of-bands.
     30
     31
     32        This patch fixes the problem by tracking the out-of-bounds access explicitly any time we go
     33        into the slow path in baseline JIT. Since we no longer miss any out-of-bounds, we can remove
     34        the slow-path heuristic.
     35
     36        There is new additional special case in the C code regarding out-of-bounds: Arguments access.
     37        Mispredicting out-of-bounds accesses on arguments is a disaster for performance, so those are
     38        tracked in the way DFG expect it.
     39
     40
     41        There are a few important cases that are still not covered optimally:
     42        -PutByVal on Arguments.
     43        -Get/Put ByVal on TypedArray.
     44        Those are simply not used by DFG in any way. TypedArrays should probably be looked at in the future.
     45
     46        * bytecode/ArrayProfile.cpp:
     47        (JSC::ArrayProfile::computeUpdatedPrediction):
     48        The inline-cache repatch cases now update the ArrayProfile information. This has no value in baseline
     49        JIT but it helps avoiding one recompile in DFG for the missing ArrayProfile information.
     50
     51        * bytecode/ArrayProfile.h:
     52        (JSC::ArrayProfile::setOutOfBounds):
     53        * dfg/DFGByteCodeParser.cpp:
     54        (JSC::DFG::ByteCodeParser::getArrayMode):
     55        (JSC::DFG::ByteCodeParser::parseBlock):
     56        (JSC::DFG::ByteCodeParser::getArrayModeConsideringSlowPath): Deleted.
     57        * jit/CCallHelpers.h:
     58        (JSC::CCallHelpers::setupArgumentsWithExecState):
     59        * jit/JIT.h:
     60        * jit/JITInlines.h:
     61        (JSC::JIT::callOperation):
     62        * jit/JITOpcodes.cpp:
     63        (JSC::JIT::emitSlow_op_has_indexed_property):
     64        * jit/JITOpcodes32_64.cpp:
     65        (JSC::JIT::emitSlow_op_has_indexed_property):
     66        * jit/JITOperations.cpp:
     67        (JSC::canUseFastArgumentAccess):
     68        This is not my favorite part of this patch.
     69
     70        I tried having JSObject::canGetIndexQuickly() handle arguments which would put everything
     71        on the generic path. Unfortunately, that code is very performance sensitive and some benchmarks were
     72        impacted by over 10%
     73
     74        I left JSObject::canGetIndexQuickly() alone, and I added the canUseFastArgumentAccess() mirroring
     75        how DFG uses out-of-bounds for Arguments.
     76
     77        (JSC::getByVal):
     78        * jit/JITOperations.h:
     79        * jit/JITPropertyAccess.cpp:
     80        (JSC::JIT::emitSlow_op_get_by_val):
     81        (JSC::JIT::emitSlow_op_put_by_val):
     82        * jit/JITPropertyAccess32_64.cpp:
     83        (JSC::JIT::emitSlow_op_get_by_val):
     84        (JSC::JIT::emitSlow_op_put_by_val):
     85        * runtime/JSPromiseFunctions.cpp:
     86        * tests/stress/get-by-val-out-of-bounds-basics.js: Added.
     87        (opaqueGetByValOnInt32ArrayEarlyOutOfBounds):
     88        (testInt32ArrayEarlyOutOfBounds):
     89        (testIndexingTypeChangesOnInt32Array):
     90        (opaqueGetByValOnStringArrayHotOutOfBounds):
     91        (testStringArrayHotOutOfBounds):
     92        (testIndexingTypeChangesOnStringArray):
     93        (opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds):
     94        (testStringAndInt32ArrayHotOutOfBounds):
     95        (opaqueGetByValOnDoubleArrayHotOutOfBounds):
     96        * tests/stress/put-by-val-out-of-bounds-basics.js: Added.
     97        (opaquePutByValOnInt32ArrayEarlyOutOfBounds):
     98        (testInt32ArrayEarlyOutOfBounds):
     99        (opaquePutByValOnStringArrayHotOutOfBounds):
     100        (testStringArrayHotOutOfBounds):
     101
    11022015-06-03  Filip Pizlo  <fpizlo@apple.com>
    2103
  • trunk/Source/JavaScriptCore/bytecode/ArrayProfile.cpp

    r183450 r185240  
    9595}
    9696
    97 void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock* codeBlock)
     97void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker& locker, CodeBlock* codeBlock)
    9898{
    9999    if (!m_lastSeenStructureID)
     
    101101   
    102102    Structure* lastSeenStructure = codeBlock->heap()->structureIDTable().get(m_lastSeenStructureID);
     103    computeUpdatedPrediction(locker, codeBlock, lastSeenStructure);
     104    m_lastSeenStructureID = 0;
     105}
     106
     107void ArrayProfile::computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock* codeBlock, Structure* lastSeenStructure)
     108{
    103109    m_observedArrayModes |= arrayModeFromStructure(lastSeenStructure);
    104110   
     
    115121        && !globalObject->isOriginalTypedArrayStructure(lastSeenStructure))
    116122        m_usesOriginalArrayStructures = false;
    117     m_lastSeenStructureID = 0;
    118123}
    119124
  • trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h

    r183450 r185240  
    210210    ArrayModes* addressOfArrayModes() { return &m_observedArrayModes; }
    211211    bool* addressOfMayStoreToHole() { return &m_mayStoreToHole; }
     212
     213    void setOutOfBounds() { m_outOfBounds = true; }
    212214    bool* addressOfOutOfBounds() { return &m_outOfBounds; }
    213215   
     
    218220   
    219221    void computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock*);
     222    void computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock*, Structure* lastSeenStructure);
    220223   
    221224    ArrayModes observedArrayModes(const ConcurrentJITLocker&) const { return m_observedArrayModes; }
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r185042 r185240  
    746746        ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
    747747        profile->computeUpdatedPrediction(locker, m_inlineStackTop->m_profiledBlock);
    748         return ArrayMode::fromObserved(locker, profile, action, false);
     748        bool makeSafe = profile->outOfBounds(locker);
     749        return ArrayMode::fromObserved(locker, profile, action, makeSafe);
    749750    }
    750751   
     
    752753    {
    753754        return getArrayMode(profile, Array::Read);
    754     }
    755    
    756     ArrayMode getArrayModeConsideringSlowPath(ArrayProfile* profile, Array::Action action)
    757     {
    758         ConcurrentJITLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
    759        
    760         profile->computeUpdatedPrediction(locker, m_inlineStackTop->m_profiledBlock);
    761        
    762         bool makeSafe =
    763             m_inlineStackTop->m_profiledBlock->likelyToTakeSlowCase(m_currentIndex)
    764             || profile->outOfBounds(locker);
    765        
    766         ArrayMode result = ArrayMode::fromObserved(locker, profile, action, makeSafe);
    767        
    768         return result;
    769755    }
    770756   
     
    31003086           
    31013087            Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
    3102             ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Read);
     3088            ArrayMode arrayMode = getArrayMode(currentInstruction[4].u.arrayProfile, Array::Read);
    31033089            Node* property = get(VirtualRegister(currentInstruction[3].u.operand));
    31043090            Node* getByVal = addToGraph(GetByVal, OpInfo(arrayMode.asWord()), OpInfo(prediction), base, property);
     
    31123098            Node* base = get(VirtualRegister(currentInstruction[1].u.operand));
    31133099
    3114             ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Write);
     3100            ArrayMode arrayMode = getArrayMode(currentInstruction[4].u.arrayProfile, Array::Write);
    31153101           
    31163102            Node* property = get(VirtualRegister(currentInstruction[2].u.operand));
     
    38653851        case op_has_indexed_property: {
    38663852            Node* base = get(VirtualRegister(currentInstruction[2].u.operand));
    3867             ArrayMode arrayMode = getArrayModeConsideringSlowPath(currentInstruction[4].u.arrayProfile, Array::Read);
     3853            ArrayMode arrayMode = getArrayMode(currentInstruction[4].u.arrayProfile, Array::Read);
    38683854            Node* property = get(VirtualRegister(currentInstruction[3].u.operand));
    38693855            Node* hasIterableProperty = addToGraph(HasIndexedProperty, OpInfo(arrayMode.asWord()), base, property);
  • trunk/Source/JavaScriptCore/jit/CCallHelpers.h

    r184324 r185240  
    733733        addCallArgument(arg5);
    734734        addCallArgument(arg6);
     735    }
     736
     737    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, TrustedImmPtr arg7)
     738    {
     739        resetCallArguments();
     740        addCallArgument(GPRInfo::callFrameRegister);
     741        addCallArgument(arg1);
     742        addCallArgument(arg2);
     743        addCallArgument(arg3);
     744        addCallArgument(arg4);
     745        addCallArgument(arg5);
     746        addCallArgument(arg6);
     747        addCallArgument(arg7);
    735748    }
    736749
     
    14671480    }
    14681481
     1482    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
     1483    {
     1484        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
     1485        poke(arg4, POKE_ARGUMENT_OFFSET);
     1486        setupArgumentsWithExecState(arg1, arg2, arg3);
     1487    }
     1488
    14691489    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3,  GPRReg arg4)
    14701490    {
     
    17211741    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5, TrustedImm32 arg6)
    17221742    {
     1743        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
     1744        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
     1745        poke(arg4, POKE_ARGUMENT_OFFSET);
     1746        setupArgumentsWithExecState(arg1, arg2, arg3);
     1747    }
     1748
     1749    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, TrustedImmPtr arg7)
     1750    {
     1751        poke(arg7, POKE_ARGUMENT_OFFSET + 3);
    17231752        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
    17241753        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
     
    18291858    {
    18301859        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3, GPRInfo::argumentGPR4>(arg1, arg3, arg4);
     1860    }
     1861
     1862    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
     1863    {
     1864        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
     1865        move(arg4, GPRInfo::argumentGPR4);
     1866        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    18311867    }
    18321868
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r184828 r185240  
    703703        MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, const Identifier*);
    704704        MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg);
     705        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*);
    705706        MacroAssembler::Call callOperation(C_JITOperation_EJsc, GPRReg);
    706707        MacroAssembler::Call callOperation(J_JITOperation_EJscC, int, GPRReg, JSCell*);
     
    744745#endif
    745746        MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID);
     747        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, ArrayProfile*);
    746748        MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, int32_t, RegisterID);
    747749        MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, int32_t);
     
    759761        MacroAssembler::Call callOperation(J_JITOperation_EJIdc, int, GPRReg, GPRReg, const Identifier*);
    760762        MacroAssembler::Call callOperation(J_JITOperation_EJJ, int, GPRReg, GPRReg, GPRReg, GPRReg);
     763        MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, GPRReg, GPRReg, ArrayProfile*);
    761764        MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, GPRReg, size_t);
    762765        MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID, RegisterID);
     
    765768        MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID, RegisterID);
    766769        MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID);
     770        MacroAssembler::Call callOperation(V_JITOperation_EJJJAp, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, ArrayProfile*);
    767771        MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, RegisterID, int32_t);
    768772        MacroAssembler::Call callOperation(V_JITOperation_EJZJ, RegisterID, RegisterID, int32_t, RegisterID, RegisterID);
  • trunk/Source/JavaScriptCore/jit/JITInlines.h

    r184828 r185240  
    400400}
    401401
     402ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJAp operation, RegisterID regOp1, RegisterID regOp2, RegisterID regOp3, ArrayProfile* arrayProfile)
     403{
     404    setupArgumentsWithExecState(regOp1, regOp2, regOp3, TrustedImmPtr(arrayProfile));
     405    return appendCallWithExceptionCheck(operation);
     406}
     407
    402408ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZJ operation, int dst, GPRReg arg)
    403409{
     
    439445{
    440446    setupArgumentsWithExecState(arg1, arg2);
     447    return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
     448}
     449
     450ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJAp operation, int dst, GPRReg arg1, GPRReg arg2, ArrayProfile* arrayProfile)
     451{
     452    setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(arrayProfile));
    441453    return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
    442454}
     
    571583}
    572584
     585ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJAp operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload, ArrayProfile* arrayProfile)
     586{
     587    setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag, TrustedImmPtr(arrayProfile));
     588    return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
     589}
     590
    573591ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_EJJ operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
    574592{
     
    628646{
    629647    setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag, SH4_32BIT_DUMMY_ARG regOp2Payload, regOp2Tag, regOp3Payload, regOp3Tag);
     648    return appendCallWithExceptionCheck(operation);
     649}
     650
     651ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJAp operation, RegisterID regOp1Tag, RegisterID regOp1Payload, RegisterID regOp2Tag, RegisterID regOp2Payload, RegisterID regOp3Tag, RegisterID regOp3Payload, ArrayProfile* arrayProfile)
     652{
     653    setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag, SH4_32BIT_DUMMY_ARG regOp2Payload, regOp2Tag, regOp3Payload, regOp3Tag, TrustedImmPtr(arrayProfile));
    630654    return appendCallWithExceptionCheck(operation);
    631655}
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r184328 r185240  
    11261126    linkSlowCaseIfNotJSCell(iter, base); // base cell check
    11271127    linkSlowCase(iter); // base array check
    1128    
    1129     Jump skipProfiling = jump();
    1130    
    11311128    linkSlowCase(iter); // vector length check
    11321129    linkSlowCase(iter); // empty value
    11331130   
    1134     emitArrayProfileOutOfBoundsSpecialCase(profile);
    1135    
    1136     skipProfiling.link(this);
    1137    
    11381131    Label slowPath = label();
    11391132   
    11401133    emitGetVirtualRegister(base, regT0);
    11411134    emitGetVirtualRegister(property, regT1);
    1142     Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT0, regT1);
     1135    Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT0, regT1, profile);
    11431136
    11441137    m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r184328 r185240  
    11231123    linkSlowCaseIfNotJSCell(iter, base); // base cell check
    11241124    linkSlowCase(iter); // base array check
    1125    
    1126     Jump skipProfiling = jump();
    1127    
    11281125    linkSlowCase(iter); // vector length check
    11291126    linkSlowCase(iter); // empty value
    1130    
    1131     emitArrayProfileOutOfBoundsSpecialCase(profile);
    1132    
    1133     skipProfiling.link(this);
    1134    
     1127
    11351128    Label slowPath = label();
    11361129   
    11371130    emitLoad(base, regT1, regT0);
    11381131    emitLoad(property, regT3, regT2);
    1139     Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT1, regT0, regT3, regT2);
     1132    Call call = callOperation(operationHasIndexedPropertyDefault, dst, regT1, regT0, regT3, regT2, profile);
    11401133
    11411134    m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r185160 r185240  
    3636#include "DFGWorklist.h"
    3737#include "Debugger.h"
     38#include "DirectArguments.h"
    3839#include "Error.h"
    3940#include "ErrorHandlingScope.h"
     
    5758#include "Repatch.h"
    5859#include "RepatchBuffer.h"
     60#include "ScopedArguments.h"
    5961#include "TestRunnerUtils.h"
    6062#include "TypeProfilerLog.h"
     
    498500}
    499501
    500 static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value)
     502static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
    501503{
    502504    VM& vm = callFrame->vm();
     
    507509            if (object->canSetIndexQuickly(i))
    508510                object->setIndexQuickly(callFrame->vm(), i, value);
    509             else
     511            else {
     512                arrayProfile->setOutOfBounds();
    510513                object->methodTable(vm)->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
     514            }
    511515        } else
    512516            baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
     
    520524}
    521525
    522 static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value)
     526static void directPutByVal(CallFrame* callFrame, JSObject* baseObject, JSValue subscript, JSValue value, ArrayProfile* arrayProfile)
    523527{
    524528    bool isStrictMode = callFrame->codeBlock()->isStrictMode();
    525529    if (LIKELY(subscript.isUInt32())) {
    526530        // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
    527         ASSERT(isIndex(subscript.asUInt32()));
    528         baseObject->putDirectIndex(callFrame, subscript.asUInt32(), value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
     531        uint32_t index = subscript.asUInt32();
     532        ASSERT(isIndex(index));
     533        if (baseObject->canSetIndexQuicklyForPutDirect(index)) {
     534            baseObject->setIndexQuickly(callFrame->vm(), index, value);
     535            return;
     536        }
     537
     538        arrayProfile->setOutOfBounds();
     539        baseObject->putDirectIndex(callFrame, index, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
    529540        return;
    530541    }
     
    551562    }
    552563}
    553 void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
     564void JIT_OPERATION operationPutByVal(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
    554565{
    555566    VM& vm = exec->vm();
     
    570581        ASSERT(!byValInfo.stubRoutine);
    571582
    572         if (hasOptimizableIndexing(object->structure(vm))) {
     583        Structure* structure = object->structure(vm);
     584        if (hasOptimizableIndexing(structure)) {
    573585            // Attempt to optimize.
    574             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
     586            JITArrayMode arrayMode = jitArrayModeForStructure(structure);
    575587            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
     588                CodeBlock* codeBlock = exec->codeBlock();
     589                ConcurrentJITLocker locker(codeBlock->m_lock);
     590                arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
     591
    576592                JIT::compilePutByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
    577593                didOptimize = true;
     
    593609    }
    594610
    595     putByVal(exec, baseValue, subscript, value);
    596 }
    597 
    598 void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
     611    putByVal(exec, baseValue, subscript, value, arrayProfile);
     612}
     613
     614void JIT_OPERATION operationDirectPutByVal(ExecState* callFrame, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
    599615{
    600616    VM& vm = callFrame->vm();
     
    614630        ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
    615631        ASSERT(!byValInfo.stubRoutine);
    616        
    617         if (hasOptimizableIndexing(object->structure(vm))) {
     632
     633        Structure* structure = object->structure(vm);
     634        if (hasOptimizableIndexing(structure)) {
    618635            // Attempt to optimize.
    619             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
     636            JITArrayMode arrayMode = jitArrayModeForStructure(structure);
    620637            if (jitArrayModePermitsPut(arrayMode) && arrayMode != byValInfo.arrayMode) {
     638                CodeBlock* codeBlock = callFrame->codeBlock();
     639                ConcurrentJITLocker locker(codeBlock->m_lock);
     640                arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
     641
    621642                JIT::compileDirectPutByVal(&vm, callFrame->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
    622643                didOptimize = true;
     
    637658        }
    638659    }
    639     directPutByVal(callFrame, object, subscript, value);
    640 }
    641 
    642 void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
     660    directPutByVal(callFrame, object, subscript, value, arrayProfile);
     661}
     662
     663void JIT_OPERATION operationPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
    643664{
    644665    VM& vm = exec->vm();
     
    649670    JSValue value = JSValue::decode(encodedValue);
    650671
    651     putByVal(exec, baseValue, subscript, value);
    652 }
    653 
    654 
    655 void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue)
     672    putByVal(exec, baseValue, subscript, value, arrayProfile);
     673}
     674
     675
     676void JIT_OPERATION operationDirectPutByValGeneric(ExecState* exec, EncodedJSValue encodedBaseValue, EncodedJSValue encodedSubscript, EncodedJSValue encodedValue, ArrayProfile* arrayProfile)
    656677{
    657678    VM& vm = exec->vm();
     
    662683    JSValue value = JSValue::decode(encodedValue);
    663684    RELEASE_ASSERT(baseValue.isObject());
    664     directPutByVal(exec, asObject(baseValue), subscript, value);
     685    directPutByVal(exec, asObject(baseValue), subscript, value, arrayProfile);
    665686}
    666687
     
    14811502}
    14821503
    1483 static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress)
     1504static bool canAccessArgumentIndexQuickly(JSObject& object, uint32_t index)
     1505{
     1506    switch (object.structure()->typeInfo().type()) {
     1507    case DirectArgumentsType: {
     1508        DirectArguments* directArguments = jsCast<DirectArguments*>(&object);
     1509        if (directArguments->canAccessArgumentIndexQuicklyInDFG(index))
     1510            return true;
     1511        break;
     1512    }
     1513    case ScopedArgumentsType: {
     1514        ScopedArguments* scopedArguments = jsCast<ScopedArguments*>(&object);
     1515        if (scopedArguments->canAccessArgumentIndexQuicklyInDFG(index))
     1516            return true;
     1517        break;
     1518    }
     1519    default:
     1520        break;
     1521    }
     1522    return false;
     1523}
     1524
     1525static JSValue getByVal(ExecState* exec, JSValue baseValue, JSValue subscript, ArrayProfile* arrayProfile, ReturnAddressPtr returnAddress)
    14841526{
    14851527    if (LIKELY(baseValue.isCell() && subscript.isString())) {
     
    14961538    if (subscript.isUInt32()) {
    14971539        uint32_t i = subscript.asUInt32();
    1498         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) {
    1499             ctiPatchCallByReturnAddress(exec->codeBlock(), returnAddress, FunctionPtr(operationGetByValString));
    1500             return asString(baseValue)->getIndex(exec, i);
    1501         }
     1540        if (isJSString(baseValue)) {
     1541            if (asString(baseValue)->canGetIndex(i)) {
     1542                ctiPatchCallByReturnAddress(exec->codeBlock(), returnAddress, FunctionPtr(operationGetByValString));
     1543                return asString(baseValue)->getIndex(exec, i);
     1544            }
     1545            arrayProfile->setOutOfBounds();
     1546        } else if (baseValue.isObject()) {
     1547            JSObject* object = asObject(baseValue);
     1548            if (object->canGetIndexQuickly(i))
     1549                return object->getIndexQuickly(i);
     1550
     1551            if (!canAccessArgumentIndexQuickly(*object, i))
     1552                arrayProfile->setOutOfBounds();
     1553        }
     1554
    15021555        return baseValue.get(exec, i);
    15031556    }
     
    15141567extern "C" {
    15151568   
    1516 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
     1569EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
    15171570{
    15181571    VM& vm = exec->vm();
     
    15211574    JSValue subscript = JSValue::decode(encodedSubscript);
    15221575
    1523     JSValue result = getByVal(exec, baseValue, subscript, ReturnAddressPtr(OUR_RETURN_ADDRESS));
     1576    JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
    15241577    return JSValue::encode(result);
    15251578}
    15261579
    1527 EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
     1580EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
    15281581{
    15291582    VM& vm = exec->vm();
     
    15441597        if (hasOptimizableIndexing(object->structure(vm))) {
    15451598            // Attempt to optimize.
    1546             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure(vm));
     1599            Structure* structure = object->structure(vm);
     1600            JITArrayMode arrayMode = jitArrayModeForStructure(structure);
    15471601            if (arrayMode != byValInfo.arrayMode) {
     1602                // If we reached this case, we got an interesting array mode we did not expect when we compiled.
     1603                // Let's update the profile to do better next time.
     1604                CodeBlock* codeBlock = exec->codeBlock();
     1605                ConcurrentJITLocker locker(codeBlock->m_lock);
     1606                arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);
     1607
    15481608                JIT::compileGetByVal(&vm, exec->codeBlock(), &byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS), arrayMode);
    15491609                didOptimize = true;
     
    15651625    }
    15661626   
    1567     JSValue result = getByVal(exec, baseValue, subscript, ReturnAddressPtr(OUR_RETURN_ADDRESS));
     1627    JSValue result = getByVal(exec, baseValue, subscript, arrayProfile, ReturnAddressPtr(OUR_RETURN_ADDRESS));
    15681628    return JSValue::encode(result);
    15691629}
    15701630   
    1571 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
     1631EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
    15721632{
    15731633    VM& vm = exec->vm();
     
    16081668        }
    16091669    }
    1610    
    1611     return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript.asUInt32())));
    1612 }
    1613    
    1614 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript)
     1670
     1671    uint32_t index = subscript.asUInt32();
     1672    if (object->canGetIndexQuickly(index))
     1673        return JSValue::encode(JSValue(JSValue::JSTrue));
     1674
     1675    if (!canAccessArgumentIndexQuickly(*object, index))
     1676        arrayProfile->setOutOfBounds();
     1677    return JSValue::encode(jsBoolean(object->hasProperty(exec, index)));
     1678}
     1679   
     1680EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile* arrayProfile)
    16151681{
    16161682    VM& vm = exec->vm();
     
    16231689
    16241690    JSObject* object = asObject(baseValue);
     1691    uint32_t index = subscript.asUInt32();
     1692    if (object->canGetIndexQuickly(index))
     1693        return JSValue::encode(JSValue(JSValue::JSTrue));
     1694
     1695    if (!canAccessArgumentIndexQuickly(*object, index))
     1696        arrayProfile->setOutOfBounds();
    16251697    return JSValue::encode(jsBoolean(object->hasProperty(exec, subscript.asUInt32())));
    16261698}
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r185160 r185240  
    5858    A: JSArray*
    5959    Aap: ArrayAllocationProfile*
     60    Ap: ArrayProfile*
    6061    C: JSCell*
    6162    Cb: CodeBlock*
     
    112113typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJIdc)(ExecState*, EncodedJSValue, const Identifier*);
    113114typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
     115typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJJAp)(ExecState*, EncodedJSValue, EncodedJSValue, ArrayProfile*);
    114116typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJssZ)(ExecState*, JSString*, int32_t);
    115117typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJP)(ExecState*, EncodedJSValue, void*);
     
    192194typedef void JIT_OPERATION (*V_JITOperation_EJIdJJ)(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue, EncodedJSValue);
    193195typedef void JIT_OPERATION (*V_JITOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
     196typedef void JIT_OPERATION (*V_JITOperation_EJJJAp)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*);
    194197typedef void JIT_OPERATION (*V_JITOperation_EJPP)(ExecState*, EncodedJSValue, void*, void*);
    195198typedef void JIT_OPERATION (*V_JITOperation_EJZJ)(ExecState*, EncodedJSValue, int32_t, EncodedJSValue);
     
    256259void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL;
    257260void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;
    258 void JIT_OPERATION operationPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
    259 void JIT_OPERATION operationDirectPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
    260 void JIT_OPERATION operationPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
    261 void JIT_OPERATION operationDirectPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
     261void JIT_OPERATION operationPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
     262void JIT_OPERATION operationDirectPutByVal(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
     263void JIT_OPERATION operationPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
     264void JIT_OPERATION operationDirectPutByValGeneric(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ArrayProfile*) WTF_INTERNAL;
    262265EncodedJSValue JIT_OPERATION operationCallEval(ExecState*, ExecState*) WTF_INTERNAL;
    263266char* JIT_OPERATION operationLinkCall(ExecState*, CallLinkInfo*) WTF_INTERNAL;
     
    316319EncodedJSValue JIT_OPERATION operationCheckHasInstance(ExecState*, EncodedJSValue, EncodedJSValue baseVal) WTF_INTERNAL;
    317320JSCell* JIT_OPERATION operationCreateActivation(ExecState*, JSScope* currentScope) WTF_INTERNAL;
    318 EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
    319 EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
     321EncodedJSValue JIT_OPERATION operationGetByValDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
     322EncodedJSValue JIT_OPERATION operationGetByValGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
    320323EncodedJSValue JIT_OPERATION operationGetByValString(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
    321 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
    322 EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) WTF_INTERNAL;
     324EncodedJSValue JIT_OPERATION operationHasIndexedPropertyDefault(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
     325EncodedJSValue JIT_OPERATION operationHasIndexedPropertyGeneric(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ArrayProfile*) WTF_INTERNAL;
    323326EncodedJSValue JIT_OPERATION operationDeleteById(ExecState*, EncodedJSValue base, const Identifier*) WTF_INTERNAL;
    324327JSCell* JIT_OPERATION operationGetPNames(ExecState*, JSObject*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r184324 r185240  
    218218    nonCell.link(this);
    219219   
    220     Jump skipProfiling = jump();
    221    
    222220    linkSlowCase(iter); // vector length check
    223221    linkSlowCase(iter); // empty value
    224222   
    225     emitArrayProfileOutOfBoundsSpecialCase(profile);
    226    
    227     skipProfiling.link(this);
    228    
    229223    Label slowPath = label();
    230224   
    231225    emitGetVirtualRegister(base, regT0);
    232226    emitGetVirtualRegister(property, regT1);
    233     Call call = callOperation(operationGetByValDefault, dst, regT0, regT1);
     227    Call call = callOperation(operationGetByValDefault, dst, regT0, regT1, profile);
    234228
    235229    m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
     
    431425    emitGetVirtualRegister(value, regT2);
    432426    bool isDirect = m_interpreter->getOpcodeID(currentInstruction->u.opcode) == op_put_by_val_direct;
    433     Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT0, regT1, regT2);
     427    Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT0, regT1, regT2, profile);
    434428
    435429    m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r184960 r185240  
    258258    notString.link(this);
    259259    nonCell.link(this);
    260    
    261     Jump skipProfiling = jump();
    262260
    263261    linkSlowCase(iter); // vector length check
    264262    linkSlowCase(iter); // empty value
    265263   
    266     emitArrayProfileOutOfBoundsSpecialCase(profile);
    267    
    268     skipProfiling.link(this);
    269    
    270264    Label slowPath = label();
    271265   
    272266    emitLoad(base, regT1, regT0);
    273267    emitLoad(property, regT3, regT2);
    274     Call call = callOperation(operationGetByValDefault, dst, regT1, regT0, regT3, regT2);
     268    Call call = callOperation(operationGetByValDefault, dst, regT1, regT0, regT3, regT2, profile);
    275269
    276270    m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath;
     
    465459    addCallArgument(regT1);
    466460    addCallArgument(regT0);
     461    addCallArgument(TrustedImmPtr(profile));
    467462    Call call = appendCallWithExceptionCheck(isDirect ? operationDirectPutByVal : operationPutByVal);
    468463#else
     
    472467    emitLoad(property, regT3, regT0);
    473468    emitLoad(value, regT5, regT4);
    474     Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT2, regT1, regT3, regT0, regT5, regT4);
     469    Call call = callOperation(isDirect ? operationDirectPutByVal : operationPutByVal, regT2, regT1, regT3, regT0, regT5, regT4, profile);
    475470#endif
    476471
  • trunk/Source/JavaScriptCore/runtime/DirectArguments.h

    r181993 r185240  
    7676        return i < m_length && (!m_overrides || !m_overrides.get()[i]);
    7777    }
    78    
     78
     79    bool canAccessArgumentIndexQuicklyInDFG(uint32_t i) const
     80    {
     81        return i < m_length && !overrodeThings();
     82    }
     83
    7984    JSValue getIndexQuickly(uint32_t i) const
    8085    {
  • trunk/Source/JavaScriptCore/runtime/JSPromiseFunctions.cpp

    r173410 r185240  
    3030
    3131#include "Error.h"
    32 #include "JSCJSValueInlines.h"
    33 #include "JSCellInlines.h"
     32#include "JSCInlines.h"
    3433#include "JSPromise.h"
    3534#include "JSPromiseConstructor.h"
  • trunk/Source/JavaScriptCore/runtime/ScopedArguments.h

    r181993 r185240  
    8181        return !!overflowStorage()[i - namedLength].get();
    8282    }
     83
     84    bool canAccessArgumentIndexQuicklyInDFG(uint32_t i) const
     85    {
     86        return canAccessIndexQuickly(i);
     87    }
    8388   
    8489    JSValue getIndexQuickly(uint32_t i) const
Note: See TracChangeset for help on using the changeset viewer.