Changeset 38917 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Dec 2, 2008, 1:52:24 PM (17 years ago)
Author:
[email protected]
Message:

2008-12-02 Geoffrey Garen <[email protected]>

Reviewed by Geoffrey Garen. (Patch by Cameron Zwarich <[email protected]>.)


Fixed https://bugs.webkit.org/show_bug.cgi?id=22482
REGRESSION (r37991): Occasionally see "Scene rendered incorrectly"
message when running the V8 Raytrace benchmark


Rolled out r37991. It didn't properly save xmm0, which is caller-save,
before calling helper functions.


SunSpider and v8 benchmarks show little change -- possibly a .2%
SunSpider regression, possibly a .2% v8 benchmark speedup.

  • assembler/X86Assembler.h: (JSC::X86Assembler::):
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump):
  • bytecode/Instruction.h: (JSC::Instruction::):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitUnaryOp):
  • bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::emitToJSNumber): (JSC::BytecodeGenerator::emitTypeOf): (JSC::BytecodeGenerator::emitGetPropertyNames):
  • interpreter/Interpreter.cpp: (JSC::Interpreter::privateExecute):
  • interpreter/Interpreter.h:
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases):
  • jit/JIT.h:
  • parser/Nodes.cpp: (JSC::UnaryOpNode::emitBytecode): (JSC::BinaryOpNode::emitBytecode): (JSC::EqualNode::emitBytecode):
  • parser/ResultType.h: (JSC::ResultType::isReusable): (JSC::ResultType::mightBeNumber):
  • runtime/JSNumberCell.h:
Location:
trunk/JavaScriptCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r38916 r38917  
     12008-12-02  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Geoffrey Garen. (Patch by Cameron Zwarich <[email protected]>.)
     4       
     5        Fixed https://bugs.webkit.org/show_bug.cgi?id=22482
     6        REGRESSION (r37991): Occasionally see "Scene rendered incorrectly"
     7        message when running the V8 Raytrace benchmark
     8       
     9        Rolled out r37991. It didn't properly save xmm0, which is caller-save,
     10        before calling helper functions.
     11       
     12        SunSpider and v8 benchmarks show little change -- possibly a .2%
     13        SunSpider regression, possibly a .2% v8 benchmark speedup.
     14
     15        * assembler/X86Assembler.h:
     16        (JSC::X86Assembler::):
     17        * bytecode/CodeBlock.cpp:
     18        (JSC::CodeBlock::dump):
     19        * bytecode/Instruction.h:
     20        (JSC::Instruction::):
     21        * bytecompiler/BytecodeGenerator.cpp:
     22        (JSC::BytecodeGenerator::emitUnaryOp):
     23        * bytecompiler/BytecodeGenerator.h:
     24        (JSC::BytecodeGenerator::emitToJSNumber):
     25        (JSC::BytecodeGenerator::emitTypeOf):
     26        (JSC::BytecodeGenerator::emitGetPropertyNames):
     27        * interpreter/Interpreter.cpp:
     28        (JSC::Interpreter::privateExecute):
     29        * interpreter/Interpreter.h:
     30        * jit/JIT.cpp:
     31        (JSC::JIT::privateCompileMainPass):
     32        (JSC::JIT::privateCompileSlowCases):
     33        * jit/JIT.h:
     34        * parser/Nodes.cpp:
     35        (JSC::UnaryOpNode::emitBytecode):
     36        (JSC::BinaryOpNode::emitBytecode):
     37        (JSC::EqualNode::emitBytecode):
     38        * parser/ResultType.h:
     39        (JSC::ResultType::isReusable):
     40        (JSC::ResultType::mightBeNumber):
     41        * runtime/JSNumberCell.h:
     42
    1432008-12-01  Gavin Barraclough  <[email protected]>
    244
  • trunk/JavaScriptCore/assembler/X86Assembler.h

    r38857 r38917  
    124124        OP2_CVTTSD2SI_GdWsd = 0x2C,
    125125        OP2_UCOMISD_VsdWsd  = 0x2E,
    126         OP2_XORPD_VsdWsd    = 0x57,
    127126        OP2_ADDSD_VsdWsd    = 0x58,
    128127        OP2_MULSD_VsdWsd    = 0x59,
     
    160159
    161160        GROUP3_OP_TEST = 0,
    162         GROUP3_OP_NEG  = 3,
    163161        GROUP3_OP_IDIV = 7,
    164162
     
    591589    }
    592590
    593     void negl_r(RegisterID dst)
    594     {
    595         m_buffer->putByte(OP_GROUP3_Ev);
    596         modRm_opr(GROUP3_OP_NEG, dst);
    597     }
    598 
    599591    void cdq()
    600592    {
     
    770762        modRm_rm((RegisterID)dst, base, offset);
    771763    }
    772 
    773 #if !PLATFORM(X86_64)
    774     void xorpd_mr(void* addr, XMMRegisterID dst)
    775     {
    776         m_buffer->putByte(PRE_SSE_66);
    777         m_buffer->putByte(OP_2BYTE_ESCAPE);
    778         m_buffer->putByte(OP2_XORPD_VsdWsd);
    779         modRm_rm((RegisterID)dst, addr);
    780     }
    781 #endif
    782764
    783765    void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
  • trunk/JavaScriptCore/bytecode/CodeBlock.cpp

    r38688 r38917  
    469469        case op_negate: {
    470470            printUnaryOp(location, it, "negate");
    471             ++it;
    472471            break;
    473472        }
  • trunk/JavaScriptCore/bytecode/Instruction.h

    r38763 r38917  
    3131
    3232#include "Opcode.h"
    33 #include "ResultType.h"
    3433#include <wtf/VectorTraits.h>
    3534
     
    139138            StructureChain* structureChain;
    140139            JSCell* jsCell;
    141             ResultType::Type resultType;
    142140            PolymorphicAccessStructureList* polymorphicStructures;
    143141        } u;
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r38887 r38917  
    750750}
    751751
    752 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src, ResultType type)
     752RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
    753753{
    754754    emitOpcode(opcodeID);
    755755    instructions().append(dst->index());
    756756    instructions().append(src->index());
    757     if (opcodeID == op_negate)
    758         instructions().append(type.toInt());
    759757    return dst;
    760758}
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r38511 r38917  
    232232        RegisterID* emitUnexpectedLoad(RegisterID* dst, double);
    233233
    234         RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src, ResultType);
     234        RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
    235235        RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
    236236        RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2);
     
    246246        RegisterID* emitMove(RegisterID* dst, RegisterID* src);
    247247
    248         RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src, ResultType::unknown()); }
     248        RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); }
    249249        RegisterID* emitPreInc(RegisterID* srcDst);
    250250        RegisterID* emitPreDec(RegisterID* srcDst);
     
    253253
    254254        RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype);
    255         RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src, ResultType::unknown()); }
     255        RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); }
    256256        RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
    257257
     
    291291        void emitSubroutineReturn(RegisterID* retAddrSrc);
    292292
    293         RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base, ResultType::unknown()); }
     293        RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); }
    294294        RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target);
    295295
  • trunk/JavaScriptCore/interpreter/Interpreter.cpp

    r38839 r38917  
    18741874        }
    18751875
    1876         ++vPC;
    18771876        NEXT_INSTRUCTION();
    18781877    }
  • trunk/JavaScriptCore/interpreter/Interpreter.h

    r38839 r38917  
    273273        static void SFX_CALL cti_op_debug(CTI_ARGS);
    274274
    275         static JSValue* SFX_CALL cti_allocate_number(CTI_ARGS);
    276 
    277275        static JSValue* SFX_CALL cti_vm_throw(CTI_ARGS);
    278276        static void* SFX_CALL cti_vm_dontLazyLinkCall(CTI_ARGS);
  • trunk/JavaScriptCore/jit/JIT.cpp

    r38916 r38917  
    362362#endif
    363363
    364 extern "C" {
    365     static JSValue* FASTCALL allocateNumber(JSGlobalData* globalData) {
    366         JSValue* result = new (globalData) JSNumberCell(globalData);
    367         ASSERT(result);
    368         return result;
    369     }
    370 }
    371 
    372 ALWAYS_INLINE void JIT::emitAllocateNumber(JSGlobalData* globalData, unsigned bytecodeIndex)
    373 {
    374     __ movl_i32r(reinterpret_cast<intptr_t>(globalData), X86::ecx);
    375     emitNakedFastCall(bytecodeIndex, (void*)allocateNumber);
    376 }
    377 
    378364ALWAYS_INLINE JmpSrc JIT::emitNakedCall(unsigned bytecodeIndex, X86::RegisterID r)
    379365{
     
    385371
    386372ALWAYS_INLINE  JmpSrc JIT::emitNakedCall(unsigned bytecodeIndex, void* function)
    387 {
    388     JmpSrc call = __ call();
    389     m_calls.append(CallRecord(call, reinterpret_cast<CTIHelper_v>(function), bytecodeIndex));
    390     return call;
    391 }
    392 
    393 ALWAYS_INLINE  JmpSrc JIT::emitNakedFastCall(unsigned bytecodeIndex, void* function)
    394373{
    395374    JmpSrc call = __ call();
     
    602581    __ addl_rr(reg, reg);
    603582    emitFastArithReTagImmediate(reg);
    604 }
    605 
    606 ALWAYS_INLINE JmpSrc JIT::emitArithIntToImmWithJump(RegisterID reg)
    607 {
    608     __ addl_rr(reg, reg);
    609     JmpSrc jmp = __ jo();
    610     emitFastArithReTagImmediate(reg);
    611     return jmp;
    612583}
    613584
     
    15971568        }
    15981569        case op_negate: {
    1599             int srcVReg = instruction[i + 2].u.operand;
    1600             emitGetVirtualRegister(srcVReg, X86::eax, i);
    1601 
    1602             __ testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
    1603             JmpSrc notImmediate = __ je();
    1604 
    1605             __ cmpl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
    1606             JmpSrc zeroImmediate = __ je();
    1607             emitFastArithImmToInt(X86::eax);
    1608             __ negl_r(X86::eax); // This can't overflow as we only have a 31bit int at this point
    1609             JmpSrc overflow = emitArithIntToImmWithJump(X86::eax);
    1610             emitPutVirtualRegister(instruction[i + 1].u.operand);
    1611             JmpSrc immediateNegateSuccess = __ jmp();
    1612 
    1613             if (!isSSE2Present()) {
    1614                 __ link(zeroImmediate, __ label());
    1615                 __ link(overflow, __ label());
    1616                 __ link(notImmediate, __ label());
    1617                 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
    1618                 emitCTICall(i, Interpreter::cti_op_negate);
    1619                 emitPutVirtualRegister(instruction[i + 1].u.operand);
    1620             } else {
    1621                 // Slow case immediates
    1622                 m_slowCases.append(SlowCaseEntry(zeroImmediate, i));
    1623                 m_slowCases.append(SlowCaseEntry(overflow, i));
    1624                 __ link(notImmediate, __ label());
    1625                 ResultType resultType(instruction[i + 3].u.resultType);
    1626                 if (!resultType.definitelyIsNumber()) {
    1627                     emitJumpSlowCaseIfNotJSCell(X86::eax, i, srcVReg);
    1628                     Structure* numberStructure = m_globalData->numberStructure.get();
    1629                     __ cmpl_i32m(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::eax);
    1630                     m_slowCases.append(SlowCaseEntry(__ jne(), i));
    1631                 }
    1632                 __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
    1633                 // We need 3 copies of the sign bit mask so we can assure alignment and pad for the 128bit load
    1634                 static double doubleSignBit[] = { -0.0, -0.0, -0.0 };
    1635                 __ xorpd_mr((void*)((((uintptr_t)doubleSignBit)+15)&~15), X86::xmm0);
    1636                 JmpSrc wasCell;
    1637                 if (!resultType.isReusableNumber())
    1638                     emitAllocateNumber(m_globalData, i);
    1639 
    1640                 putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, instruction[i + 1].u.operand, &wasCell,
    1641                                                            X86::xmm1, X86::ecx, X86::edx);
    1642                 __ link(wasCell, __ label());
    1643             }
    1644             __ link(immediateNegateSuccess, __ label());
    1645             i += 4;
     1570            emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
     1571            emitCTICall(i, Interpreter::cti_op_negate);
     1572            emitPutVirtualRegister(instruction[i + 1].u.operand);
     1573            i += 3;
    16461574            break;
    16471575        }
     
    24862414            break;
    24872415        }
    2488         case op_negate: {
    2489             __ link(iter->from, __ label());
    2490             __ link((++iter)->from, __ label());
    2491             ResultType resultType(instruction[i + 3].u.resultType);
    2492             if (!resultType.definitelyIsNumber()) {
    2493                 if (linkSlowCaseIfNotJSCell(++iter, instruction[i + 2].u.operand))
    2494                     ++iter;
    2495                 __ link(iter->from, __ label());
    2496             }
    2497 
    2498             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
    2499             emitCTICall(i, Interpreter::cti_op_negate);
    2500             emitPutVirtualRegister(instruction[i + 1].u.operand);
    2501             i += 4;
    2502             break;
    2503         }
    25042416        case op_rshift: {
    25052417            __ link(iter->from, __ label());
  • trunk/JavaScriptCore/jit/JIT.h

    r38916 r38917  
    8787#define CTI_RETURN_ADDRESS_SLOT (ARGS[-1])
    8888
    89 #if COMPILER(MSVC)
    90 #define FASTCALL __fastcall
    91 #elif COMPILER(GCC)
    92 #define FASTCALL  __attribute__ ((fastcall))
    93 #else
    94 #error Need to support fastcall calling convention in this compiler
    95 #endif
    96 
    9789namespace JSC {
    9890
     
    449441        void emitFastArithIntToImmOrSlowCase(RegisterID, unsigned bytecodeIndex);
    450442        void emitFastArithIntToImmNoCheck(RegisterID);
    451         JmpSrc emitArithIntToImmWithJump(RegisterID reg);
    452443
    453444        void emitTagAsBoolImmediate(RegisterID reg);
    454 
    455         void emitAllocateNumber(JSGlobalData*, unsigned);
    456445
    457446        JmpSrc emitNakedCall(unsigned bytecodeIndex, RegisterID);
    458447        JmpSrc emitNakedCall(unsigned bytecodeIndex, void* function);
    459         JmpSrc emitNakedFastCall(unsigned bytecodeIndex, void*);
    460448        JmpSrc emitCTICall(unsigned bytecodeIndex, CTIHelper_j);
    461449        JmpSrc emitCTICall(unsigned bytecodeIndex, CTIHelper_o);
  • trunk/JavaScriptCore/parser/Nodes.cpp

    r38747 r38917  
    10941094{
    10951095    RegisterID* src = generator.emitNode(m_expr.get());
    1096     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src, m_expr->resultDescriptor());
     1096    return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
    10971097}
    10981098
     
    11161116        if (m_expr1->isNull() || m_expr2->isNull()) {
    11171117            RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
    1118             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
     1118            return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
    11191119        }
    11201120    }
     
    11291129    if (m_expr1->isNull() || m_expr2->isNull()) {
    11301130        RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
    1131         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get(), ResultType::unknown());
     1131        return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
    11321132    }
    11331133
  • trunk/JavaScriptCore/parser/ResultType.h

    r38205 r38917  
    5353            return (m_type & TypeReusable);
    5454        }
    55        
    56         bool isReusableNumber()
    57         {
    58             return isReusable() && definitelyIsNumber();
    59         }
    6055
    6156        bool definitelyIsNumber()
     
    7267        {
    7368            return !isNotNumber();
    74         }
    75        
    76         int toInt()
    77         {
    78             return static_cast<int>(m_type);
    7969        }
    8070
  • trunk/JavaScriptCore/runtime/JSNumberCell.h

    r38528 r38917  
    8585        static PassRefPtr<Structure> createStructure(JSValue* proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
    8686
    87         JSNumberCell(JSGlobalData* globalData)
    88         : JSCell(globalData->numberStructure.get())
    89         {
    90         }
    91 
    9287    private:
    9388        JSNumberCell(JSGlobalData* globalData, double value)
Note: See TracChangeset for help on using the changeset viewer.