Changeset 96238 in webkit


Ignore:
Timestamp:
Sep 28, 2011 11:05:03 AM (13 years ago)
Author:
barraclough@apple.com
Message:

Value profiling in baseline JIT for JSVALUE32_64
https://bugs.webkit.org/show_bug.cgi?id=68750

Patch by Yuqiang Xian <yuqiang.xian@intel.com> on 2011-09-27
Reviewed by Geoff Garen.

  • jit/JITArithmetic32_64.cpp:

(JSC::JIT::emit_op_mul):
(JSC::JIT::emit_op_div):

  • jit/JITCall32_64.cpp:

(JSC::JIT::emit_op_call_put_result):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_resolve):
(JSC::JIT::emit_op_resolve_base):
(JSC::JIT::emit_op_resolve_skip):
(JSC::JIT::emit_op_resolve_global):
(JSC::JIT::emitSlow_op_resolve_global):
(JSC::JIT::emit_op_resolve_with_base):
(JSC::JIT::emit_op_resolve_with_this):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_method_check):
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emitSlow_op_get_by_id):
(JSC::JIT::emit_op_get_scoped_var):
(JSC::JIT::emit_op_get_global_var):

  • jit/JITStubCall.h:

(JSC::JITStubCall::callWithValueProfiling):

Location:
trunk/Source/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r96230 r96238  
     12011-09-27  Yuqiang Xian  <yuqiang.xian@intel.com>
     2
     3        Value profiling in baseline JIT for JSVALUE32_64
     4        https://bugs.webkit.org/show_bug.cgi?id=68750
     5
     6        Reviewed by Geoff Garen.
     7
     8        * jit/JITArithmetic32_64.cpp:
     9        (JSC::JIT::emit_op_mul):
     10        (JSC::JIT::emit_op_div):
     11        * jit/JITCall32_64.cpp:
     12        (JSC::JIT::emit_op_call_put_result):
     13        * jit/JITOpcodes32_64.cpp:
     14        (JSC::JIT::emit_op_resolve):
     15        (JSC::JIT::emit_op_resolve_base):
     16        (JSC::JIT::emit_op_resolve_skip):
     17        (JSC::JIT::emit_op_resolve_global):
     18        (JSC::JIT::emitSlow_op_resolve_global):
     19        (JSC::JIT::emit_op_resolve_with_base):
     20        (JSC::JIT::emit_op_resolve_with_this):
     21        * jit/JITPropertyAccess32_64.cpp:
     22        (JSC::JIT::emit_op_method_check):
     23        (JSC::JIT::emit_op_get_by_val):
     24        (JSC::JIT::emitSlow_op_get_by_val):
     25        (JSC::JIT::emit_op_get_by_id):
     26        (JSC::JIT::emitSlow_op_get_by_id):
     27        (JSC::JIT::emit_op_get_scoped_var):
     28        (JSC::JIT::emit_op_get_global_var):
     29        * jit/JITStubCall.h:
     30        (JSC::JITStubCall::callWithValueProfiling):
     31
    1322011-09-28  Yuqiang Xian  <yuqiang.xian@intel.com>
    233
  • trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp

    r95901 r96238  
    10491049    divDouble(fpRegT1, fpRegT0);
    10501050   
    1051 #if ENABLE(DFG_JIT)
     1051#if ENABLE(VALUE_PROFILER)
    10521052    // Is the result actually an integer? The DFG JIT would really like to know. If it's
    10531053    // not an integer, we increment a count. If this together with the slow case counter
  • trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp

    r95901 r96238  
    859859                emitStoreDouble(dst, fpRegT1);
    860860                break;
    861             case op_div:
     861            case op_div: {
    862862                emitLoadDouble(op1, fpRegT1);
    863863                divDouble(fpRegT0, fpRegT1);
     864
     865#if ENABLE(VALUE_PROFILER)
     866                // Is the result actually an integer? The DFG JIT would really like to know. If it's
     867                // not an integer, we increment a count. If this together with the slow case counter
     868                // are below threshold then the DFG JIT will compile this division with a specualtion
     869                // that the remainder is zero.
     870               
     871                // As well, there are cases where a double result here would cause an important field
     872                // in the heap to sometimes have doubles in it, resulting in double predictions getting
     873                // propagated to a use site where it might cause damage (such as the index to an array
     874                // access). So if we are DFG compiling anything in the program, we want this code to
     875                // ensure that it produces integers whenever possible.
     876               
     877                // FIXME: This will fail to convert to integer if the result is zero. We should
     878                // distinguish between positive zero and negative zero here.
     879               
     880                JumpList notInteger;
     881                branchConvertDoubleToInt32(fpRegT1, regT2, notInteger, fpRegT0);
     882                // If we've got an integer, we might as well make that the result of the division.
     883                emitStoreInt32(dst, regT2);
     884                Jump isInteger = jump();
     885                notInteger.link(this);
     886                add32(Imm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
    864887                emitStoreDouble(dst, fpRegT1);
    865                 break;
     888                isInteger.link(this);
     889#else
     890                emitStoreDouble(dst, fpRegT1);
     891#endif
     892                break;
     893            }
    866894            case op_jless:
    867895                emitLoadDouble(op1, fpRegT2);
     
    936964                emitStoreDouble(dst, fpRegT0);
    937965                break;
    938             case op_div:
     966            case op_div: {
    939967                emitLoadDouble(op2, fpRegT2);
    940968                divDouble(fpRegT2, fpRegT0);
     969#if ENABLE(VALUE_PROFILER)
     970                // Is the result actually an integer? The DFG JIT would really like to know. If it's
     971                // not an integer, we increment a count. If this together with the slow case counter
     972                // are below threshold then the DFG JIT will compile this division with a specualtion
     973                // that the remainder is zero.
     974               
     975                // As well, there are cases where a double result here would cause an important field
     976                // in the heap to sometimes have doubles in it, resulting in double predictions getting
     977                // propagated to a use site where it might cause damage (such as the index to an array
     978                // access). So if we are DFG compiling anything in the program, we want this code to
     979                // ensure that it produces integers whenever possible.
     980               
     981                // FIXME: This will fail to convert to integer if the result is zero. We should
     982                // distinguish between positive zero and negative zero here.
     983               
     984                JumpList notInteger;
     985                branchConvertDoubleToInt32(fpRegT0, regT2, notInteger, fpRegT1);
     986                // If we've got an integer, we might as well make that the result of the division.
     987                emitStoreInt32(dst, regT2);
     988                Jump isInteger = jump();
     989                notInteger.link(this);
     990                add32(Imm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
    941991                emitStoreDouble(dst, fpRegT0);
    942                 break;
     992                isInteger.link(this);
     993#else
     994                emitStoreDouble(dst, fpRegT0);
     995#endif
     996                break;
     997            }
    943998            case op_jless:
    944999                emitLoadDouble(op2, fpRegT1);
     
    9891044    unsigned op2 = currentInstruction[3].u.operand;
    9901045    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     1046
     1047#if ENABLE(VALUE_PROFILER)
     1048    m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset);
     1049#endif
    9911050
    9921051    JumpList notInt32Op1;
     
    10311090
    10321091    negZero.link(this);
     1092#if ENABLE(VALUE_PROFILER)
     1093    // We only get here if we have a genuine negative zero. Record this,
     1094    // so that the speculative JIT knows that we failed speculation
     1095    // because of a negative zero.
     1096    add32(Imm32(1), AbsoluteAddress(&m_codeBlock->specialFastCaseProfileForBytecodeOffset(m_bytecodeOffset)->m_counter));
     1097#endif
    10331098    overflow.link(this);
    10341099
     
    10631128    unsigned op2 = currentInstruction[3].u.operand;
    10641129    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     1130
     1131#if ENABLE(VALUE_PROFILER)
     1132    m_codeBlock->addSpecialFastCaseProfile(m_bytecodeOffset);
     1133#endif
    10651134
    10661135    if (!supportsFloatingPoint()) {
  • trunk/Source/JavaScriptCore/jit/JITCall32_64.cpp

    r95901 r96238  
    5959{
    6060    int dst = instruction[1].u.operand;
     61    emitValueProfilingSite(FirstProfilingSite);
    6162    emitStore(dst, regT1, regT0);
    6263}
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r95901 r96238  
    617617    JITStubCall stubCall(this, cti_op_resolve);
    618618    stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
    619     stubCall.call(currentInstruction[1].u.operand);
     619    stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite);
    620620}
    621621
     
    659659    JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
    660660    stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
    661     stubCall.call(currentInstruction[1].u.operand);
     661    stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite);
    662662}
    663663
     
    675675    stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
    676676    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
    677     stubCall.call(currentInstruction[1].u.operand);
     677    stubCall.callWithValueProfiling(currentInstruction[1].u.operand, FirstProfilingSite);
    678678}
    679679
     
    700700    load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
    701701    load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
     702    emitValueProfilingSite(FirstProfilingSite);
    702703    emitStore(dst, regT1, regT0);
    703704    map(m_bytecodeOffset + (dynamic ? OPCODE_LENGTH(op_resolve_global_dynamic) : OPCODE_LENGTH(op_resolve_global)), dst, regT1, regT0);
     
    715716    stubCall.addArgument(TrustedImmPtr(ident));
    716717    stubCall.addArgument(Imm32(currentIndex));
    717     stubCall.call(dst);
     718    stubCall.callWithValueProfiling(dst, SubsequentProfilingSite);
    718719}
    719720
     
    11131114    stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
    11141115    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
    1115     stubCall.call(currentInstruction[2].u.operand);
     1116    stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite);
    11161117}
    11171118
     
    11211122    stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
    11221123    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
    1123     stubCall.call(currentInstruction[2].u.operand);
     1124    stubCall.callWithValueProfiling(currentInstruction[2].u.operand, FirstProfilingSite);
    11241125}
    11251126
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r95965 r96238  
    145145   
    146146    match.link(this);
     147    emitValueProfilingSite(FirstProfilingSite);
    147148    emitStore(dst, regT1, regT0);
    148149    map(m_bytecodeOffset + OPCODE_LENGTH(op_method_check), dst, regT1, regT0);
     
    217218    addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag)));
    218219   
     220    emitValueProfilingSite(FirstProfilingSite);
    219221    emitStore(dst, regT1, regT0);
    220222    map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0);
     
    248250    stubCall.addArgument(property);
    249251    stubCall.call(dst);
     252
     253    emitValueProfilingSite(SubsequentProfilingSite);
    250254}
    251255
     
    311315    emitJumpSlowCaseIfNotJSCell(base, regT1);
    312316    compileGetByIdHotPath();
     317    emitValueProfilingSite(FirstProfilingSite);
    313318    emitStore(dst, regT1, regT0);
    314319    map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_id), dst, regT1, regT0);
     
    354359   
    355360    compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter);
     361    emitValueProfilingSite(SubsequentProfilingSite);
    356362}
    357363
     
    10181024
    10191025    emitLoad(index, regT1, regT0, regT2);
     1026    emitValueProfilingSite(FirstProfilingSite);
    10201027    emitStore(dst, regT1, regT0);
    10211028    map(m_bytecodeOffset + OPCODE_LENGTH(op_get_scoped_var), dst, regT1, regT0);
     
    10591066
    10601067    emitLoad(index, regT1, regT0, regT2);
     1068    emitValueProfilingSite(FirstProfilingSite);
    10611069    emitStore(dst, regT1, regT0);
    10621070    map(m_bytecodeOffset + OPCODE_LENGTH(op_get_global_var), dst, regT1, regT0);
  • trunk/Source/JavaScriptCore/jit/JITStubCall.h

    r95901 r96238  
    202202        }
    203203       
    204         JIT::Call callWithValueProfiling(unsigned dst, JIT::ValueProfilingSiteKind)
    205         {
    206             return call(dst);
     204        JIT::Call callWithValueProfiling(unsigned dst, JIT::ValueProfilingSiteKind kind)
     205        {
     206            ASSERT(m_returnType == Value || m_returnType == Cell);
     207            JIT::Call call = this->call();
     208            m_jit->emitValueProfilingSite(kind);
     209            if (m_returnType == Value)
     210                m_jit->emitStore(dst, JIT::regT1, JIT::regT0);
     211            else
     212                m_jit->emitStoreCell(dst, JIT::returnValueRegister);
     213            return call;
    207214        }
    208215#else
Note: See TracChangeset for help on using the changeset viewer.