Changeset 83230 in webkit


Ignore:
Timestamp:
Apr 7, 2011 4:47:06 PM (13 years ago)
Author:
barraclough@apple.com
Message:

Mapping booleans the same way as integers
https://bugs.webkit.org/show_bug.cgi?id=56913

Patch by Zoltan Herczeg <zherczeg@webkit.org> on 2011-04-07
Reviewed by Gavin Barraclough.

Instead of having a seperate tag field for booleans,
the logical values are stored in the payload field
(for JSValue32_64 representation).

1.007x speedup on SunSpider.

  • jit/JIT.h:
  • jit/JITInlineMethods.h:

(JSC::JIT::emitStoreBool):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_instanceof):
(JSC::JIT::emit_op_not):
(JSC::JIT::emit_op_jfalse):
(JSC::JIT::emitSlow_op_jfalse):
(JSC::JIT::emit_op_jtrue):
(JSC::JIT::emitSlow_op_jtrue):
(JSC::JIT::emit_op_jeq_null):
(JSC::JIT::emit_op_jneq_null):
(JSC::JIT::emit_op_eq):
(JSC::JIT::emitSlow_op_eq):
(JSC::JIT::emit_op_neq):
(JSC::JIT::emitSlow_op_neq):
(JSC::JIT::compileOpStrictEq):
(JSC::JIT::emit_op_eq_null):
(JSC::JIT::emit_op_neq_null):

  • jit/JSInterfaceJIT.h:
  • runtime/JSValue.h:

(JSC::JSValue::JSValue):
(JSC::JSValue::isTrue):
(JSC::JSValue::isFalse):
(JSC::JSValue::getBoolean):

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r83225 r83230  
     12011-04-07  Zoltan Herczeg  <zherczeg@webkit.org>
     2
     3        Reviewed by Gavin Barraclough.
     4
     5        Mapping booleans the same way as integers
     6        https://bugs.webkit.org/show_bug.cgi?id=56913
     7
     8        Instead of having a seperate tag field for booleans,
     9        the logical values are stored in the payload field
     10        (for JSValue32_64 representation).
     11
     12        1.007x speedup on SunSpider.
     13
     14        * jit/JIT.h:
     15        * jit/JITInlineMethods.h:
     16        (JSC::JIT::emitStoreBool):
     17        * jit/JITOpcodes32_64.cpp:
     18        (JSC::JIT::emit_op_instanceof):
     19        (JSC::JIT::emit_op_not):
     20        (JSC::JIT::emit_op_jfalse):
     21        (JSC::JIT::emitSlow_op_jfalse):
     22        (JSC::JIT::emit_op_jtrue):
     23        (JSC::JIT::emitSlow_op_jtrue):
     24        (JSC::JIT::emit_op_jeq_null):
     25        (JSC::JIT::emit_op_jneq_null):
     26        (JSC::JIT::emit_op_eq):
     27        (JSC::JIT::emitSlow_op_eq):
     28        (JSC::JIT::emit_op_neq):
     29        (JSC::JIT::emitSlow_op_neq):
     30        (JSC::JIT::compileOpStrictEq):
     31        (JSC::JIT::emit_op_eq_null):
     32        (JSC::JIT::emit_op_neq_null):
     33        * jit/JSInterfaceJIT.h:
     34        * runtime/JSValue.h:
     35        (JSC::JSValue::JSValue):
     36        (JSC::JSValue::isTrue):
     37        (JSC::JSValue::isFalse):
     38        (JSC::JSValue::getBoolean):
     39
    1402011-04-07  Eric Seidel  <eric@webkit.org>
    241
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r82130 r83230  
    312312        void emitStoreInt32(unsigned index, TrustedImm32 payload, bool indexIsInt32 = false);
    313313        void emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell = false);
    314         void emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool = false);
     314        void emitStoreBool(unsigned index, RegisterID payload, bool indexIsBool = false);
    315315        void emitStoreDouble(unsigned index, FPRegisterID value);
    316316
  • trunk/Source/JavaScriptCore/jit/JITInlineMethods.h

    r83192 r83230  
    454454}
    455455
    456 inline void JIT::emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool)
    457 {
     456inline void JIT::emitStoreBool(unsigned index, RegisterID payload, bool indexIsBool)
     457{
     458    store32(payload, payloadFor(index, callFrameRegister));
    458459    if (!indexIsBool)
    459         store32(TrustedImm32(0), payloadFor(index, callFrameRegister));
    460     store32(tag, tagFor(index, callFrameRegister));
     460        store32(TrustedImm32(JSValue::BooleanTag), tagFor(index, callFrameRegister));
    461461}
    462462
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r82849 r83230  
    554554    // Initially, regT1 still contains proto and regT2 still contains value.
    555555    // As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
    556     move(TrustedImm32(JSValue::TrueTag), regT0);
     556    move(TrustedImm32(1), regT0);
    557557    Label loop(this);
    558558
     
    565565
    566566    // We get here either by dropping out of the loop, or if value was not an Object.  Result is false.
    567     move(TrustedImm32(JSValue::FalseTag), regT0);
     567    move(TrustedImm32(0), regT0);
    568568
    569569    // isInstance jumps right down to here, to skip setting the result to false (it has already set true).
     
    830830    emitLoadTag(src, regT0);
    831831
    832     xor32(TrustedImm32(JSValue::FalseTag), regT0);
    833     addSlowCase(branchTest32(NonZero, regT0, TrustedImm32(~1)));
    834     xor32(TrustedImm32(JSValue::TrueTag), regT0);
     832    emitLoad(src, regT1, regT0);
     833    addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::BooleanTag)));
     834    xor32(TrustedImm32(1), regT0);
    835835
    836836    emitStoreBool(dst, regT0, (dst == src));
     
    856856    emitLoad(cond, regT1, regT0);
    857857
    858     Jump isTrue = branch32(Equal, regT1, TrustedImm32(JSValue::TrueTag));
    859     addJump(branch32(Equal, regT1, TrustedImm32(JSValue::FalseTag)), target);
    860 
    861     Jump isNotInteger = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
    862     Jump isTrue2 = branch32(NotEqual, regT0, TrustedImm32(0));
    863     addJump(jump(), target);
    864 
    865     if (supportsFloatingPoint()) {
    866         isNotInteger.link(this);
    867 
    868         addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
    869 
    870         emitLoadDouble(cond, fpRegT0);
    871         addJump(branchDoubleZeroOrNaN(fpRegT0, fpRegT1), target);
    872     } else
    873         addSlowCase(isNotInteger);
    874 
    875     isTrue.link(this);
    876     isTrue2.link(this);
     858    ASSERT((JSValue::BooleanTag + 1 == JSValue::Int32Tag) && !(JSValue::Int32Tag + 1));
     859    addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::BooleanTag)));
     860    addJump(branchTest32(Zero, regT0), target);
    877861}
    878862
     
    883867
    884868    linkSlowCase(iter);
     869
     870    if (supportsFloatingPoint()) {
     871        // regT1 contains the tag from the hot path.
     872        Jump notNumber = branch32(Above, regT1, Imm32(JSValue::LowestTag));
     873
     874        emitLoadDouble(cond, fpRegT0);
     875        emitJumpSlowToHot(branchDoubleZeroOrNaN(fpRegT0, fpRegT1), target);
     876        emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jfalse));
     877
     878        notNumber.link(this);
     879    }
     880
    885881    JITStubCall stubCall(this, cti_op_jtrue);
    886882    stubCall.addArgument(cond);
     
    896892    emitLoad(cond, regT1, regT0);
    897893
    898     Jump isFalse = branch32(Equal, regT1, TrustedImm32(JSValue::FalseTag));
    899     addJump(branch32(Equal, regT1, TrustedImm32(JSValue::TrueTag)), target);
    900 
    901     Jump isNotInteger = branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag));
    902     Jump isFalse2 = branch32(Equal, regT0, TrustedImm32(0));
    903     addJump(jump(), target);
    904 
    905     if (supportsFloatingPoint()) {
    906         isNotInteger.link(this);
    907 
    908         addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
    909 
    910         emitLoadDouble(cond, fpRegT0);
    911         addJump(branchDoubleNonZero(fpRegT0, fpRegT1), target);
    912     } else
    913         addSlowCase(isNotInteger);
    914 
    915     isFalse.link(this);
    916     isFalse2.link(this);
     894    ASSERT((JSValue::BooleanTag + 1 == JSValue::Int32Tag) && !(JSValue::Int32Tag + 1));
     895    addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::BooleanTag)));
     896    addJump(branchTest32(NonZero, regT0), target);
    917897}
    918898
     
    923903
    924904    linkSlowCase(iter);
     905
     906    if (supportsFloatingPoint()) {
     907        // regT1 contains the tag from the hot path.
     908        Jump notNumber = branch32(Above, regT1, Imm32(JSValue::LowestTag));
     909
     910        emitLoadDouble(cond, fpRegT0);
     911        emitJumpSlowToHot(branchDoubleNonZero(fpRegT0, fpRegT1), target);
     912        emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jtrue));
     913
     914        notNumber.link(this);
     915    }
     916
    925917    JITStubCall stubCall(this, cti_op_jtrue);
    926918    stubCall.addArgument(cond);
     
    947939    isImmediate.link(this);
    948940
    949     ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1));
    950     addJump(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::UndefinedTag)), target);
     941    ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1));
     942    or32(TrustedImm32(1), regT1);
     943    addJump(branch32(Equal, regT1, TrustedImm32(JSValue::NullTag)), target);
    951944
    952945    wasNotImmediate.link(this);
     
    971964    isImmediate.link(this);
    972965
    973     ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && !(JSValue::NullTag + 1));
    974     addJump(branch32(Below, regT1, TrustedImm32(JSValue::UndefinedTag)), target);
     966    ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1));
     967    or32(TrustedImm32(1), regT1);
     968    addJump(branch32(NotEqual, regT1, TrustedImm32(JSValue::NullTag)), target);
    975969
    976970    wasNotImmediate.link(this);
     
    10131007    addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
    10141008
    1015     set8Compare32(Equal, regT0, regT2, regT0);
    1016     or32(TrustedImm32(JSValue::FalseTag), regT0);
     1009    set32Compare32(Equal, regT0, regT2, regT0);
    10171010
    10181011    emitStoreBool(dst, regT0);
     
    10501043
    10511044    storeResult.link(this);
    1052     or32(TrustedImm32(JSValue::FalseTag), regT0);
    10531045    emitStoreBool(dst, regT0);
    10541046}
     
    10651057    addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
    10661058
    1067     set8Compare32(NotEqual, regT0, regT2, regT0);
    1068     or32(TrustedImm32(JSValue::FalseTag), regT0);
     1059    set32Compare32(NotEqual, regT0, regT2, regT0);
    10691060
    10701061    emitStoreBool(dst, regT0);
     
    11011092    storeResult.link(this);
    11021093    xor32(TrustedImm32(0x1), regT0);
    1103     or32(TrustedImm32(JSValue::FalseTag), regT0);
    11041094    emitStoreBool(dst, regT0);
    11051095}
     
    11221112
    11231113    if (type == OpStrictEq)
    1124         set8Compare32(Equal, regT0, regT1, regT0);
     1114        set32Compare32(Equal, regT0, regT1, regT0);
    11251115    else
    1126         set8Compare32(NotEqual, regT0, regT1, regT0);
    1127 
    1128     or32(TrustedImm32(JSValue::FalseTag), regT0);
     1116        set32Compare32(NotEqual, regT0, regT1, regT0);
    11291117
    11301118    emitStoreBool(dst, regT0);
     
    11861174    isImmediate.link(this);
    11871175
    1188     set8Compare32(Equal, regT1, TrustedImm32(JSValue::NullTag), regT2);
    1189     set8Compare32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
     1176    set32Compare32(Equal, regT1, TrustedImm32(JSValue::NullTag), regT2);
     1177    set32Compare32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
    11901178    or32(regT2, regT1);
    11911179
    11921180    wasNotImmediate.link(this);
    1193 
    1194     or32(TrustedImm32(JSValue::FalseTag), regT1);
    11951181
    11961182    emitStoreBool(dst, regT1);
     
    12121198    isImmediate.link(this);
    12131199
    1214     set8Compare32(NotEqual, regT1, TrustedImm32(JSValue::NullTag), regT2);
    1215     set8Compare32(NotEqual, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
     1200    set32Compare32(NotEqual, regT1, TrustedImm32(JSValue::NullTag), regT2);
     1201    set32Compare32(NotEqual, regT1, TrustedImm32(JSValue::UndefinedTag), regT1);
    12161202    and32(regT2, regT1);
    12171203
    12181204    wasNotImmediate.link(this);
    1219 
    1220     or32(TrustedImm32(JSValue::FalseTag), regT1);
    12211205
    12221206    emitStoreBool(dst, regT1);
  • trunk/Source/JavaScriptCore/jit/JSInterfaceJIT.h

    r82130 r83230  
    161161#if USE(JSVALUE32_64)
    162162        // Can't just propogate JSValue::Int32Tag as visual studio doesn't like it
    163         static const unsigned Int32Tag = 0xfffffffd;
     163        static const unsigned Int32Tag = 0xffffffff;
    164164        COMPILE_ASSERT(Int32Tag == JSValue::Int32Tag, Int32Tag_out_of_sync);
    165165#else
  • trunk/Source/JavaScriptCore/runtime/JSValue.h

    r83106 r83230  
    269269         * For JSValues that do not contain a double value, the high 32 bits contain the tag
    270270         * values listed in the enums below, which all correspond to NaN-space. In the case of
    271          * cell and integer values the lower 32 bits (the 'payload') contain the pointer or
    272          * integer value; in the case of all other tags the payload is 0.
     271         * cell, integer and bool values the lower 32 bits (the 'payload') contain the pointer
     272         * integer or boolean value; in the case of all other tags the payload is 0.
    273273         */
    274         enum { NullTag =         0xffffffff };
    275         enum { UndefinedTag =    0xfffffffe };
    276         enum { Int32Tag =        0xfffffffd };
    277         enum { CellTag =         0xfffffffc };
    278         enum { TrueTag =         0xfffffffb };
    279         enum { FalseTag =        0xfffffffa };
    280         enum { EmptyValueTag =   0xfffffff9 };
    281         enum { DeletedValueTag = 0xfffffff8 };
    282        
     274        enum { Int32Tag =        0xffffffff };
     275        enum { BooleanTag =      0xfffffffe };
     276        enum { NullTag =         0xfffffffd };
     277        enum { UndefinedTag =    0xfffffffc };
     278        enum { CellTag =         0xfffffffb };
     279        enum { EmptyValueTag =   0xfffffffa };
     280        enum { DeletedValueTag = 0xfffffff9 };
     281
    283282        enum { LowestTag =  DeletedValueTag };
    284283
     
    444443    inline JSValue::JSValue(JSTrueTag)
    445444    {
    446         u.asBits.tag = TrueTag;
    447         u.asBits.payload = 0;
     445        u.asBits.tag = BooleanTag;
     446        u.asBits.payload = 1;
    448447    }
    449448   
    450449    inline JSValue::JSValue(JSFalseTag)
    451450    {
    452         u.asBits.tag = FalseTag;
     451        u.asBits.tag = BooleanTag;
    453452        u.asBits.payload = 0;
    454453    }
     
    537536    inline bool JSValue::isTrue() const
    538537    {
    539         return tag() == TrueTag;
     538        return tag() == BooleanTag && payload();
    540539    }
    541540
    542541    inline bool JSValue::isFalse() const
    543542    {
    544         return tag() == FalseTag;
     543        return tag() == BooleanTag && !payload();
    545544    }
    546545
     
    692691    {
    693692        ASSERT(isBoolean());
    694         return tag() == TrueTag;
     693        return payload();
    695694    }
    696695
Note: See TracChangeset for help on using the changeset viewer.