Ignore:
Timestamp:
Apr 28, 2010, 8:57:16 PM (15 years ago)
Author:
[email protected]
Message:

2010-04-28 Oliver Hunt <[email protected]>

Reviewed by Gavin Barraclough.

Add fast paths for Math.pow and Math.sqrt
https://bugs.webkit.org/show_bug.cgi?id=38294

Add specialized thunks for Math.pow and Math.sqrt.
This requires adding a sqrtDouble function to the MacroAssembler
and sqrtsd to the x86 assembler.

Math.pow is slightly more complicated, in that we have
to implement exponentiation ourselves rather than relying
on hardware support. The inline exponentiation is restricted
to positive integer exponents on a numeric base. Exponentiation
is finally performed through the "Exponentiation by Squaring"
algorithm.

  • assembler/AbstractMacroAssembler.h: (JSC::AbstractMacroAssembler::ImmPtr::ImmPtr):
  • assembler/MacroAssemblerARM.h: (JSC::MacroAssemblerARM::supportsFloatingPointSqrt): (JSC::MacroAssemblerARM::loadDouble): (JSC::MacroAssemblerARM::sqrtDouble):
  • assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::supportsFloatingPointSqrt): (JSC::MacroAssemblerARMv7::sqrtDouble):
  • assembler/MacroAssemblerX86.h: (JSC::MacroAssemblerX86::loadDouble): (JSC::MacroAssemblerX86::supportsFloatingPointSqrt):
  • assembler/MacroAssemblerX86Common.h: (JSC::MacroAssemblerX86Common::sqrtDouble):
  • assembler/MacroAssemblerX86_64.h: (JSC::MacroAssemblerX86_64::loadDouble): (JSC::MacroAssemblerX86_64::supportsFloatingPointSqrt):
  • assembler/X86Assembler.h: (JSC::X86Assembler::): (JSC::X86Assembler::movsd_mr): (JSC::X86Assembler::sqrtsd_rr): (JSC::X86Assembler::X86InstructionFormatter::twoByteOp): (JSC::X86Assembler::X86InstructionFormatter::memoryModRM):
  • create_hash_table:
  • jit/JIT.h:
  • jit/JITInlineMethods.h:
  • jit/JITOpcodes.cpp:
  • jit/JITStubs.h: (JSC::JITThunks::ctiNativeCallThunk):
  • jit/JSInterfaceJIT.h: (JSC::JSInterfaceJIT::emitLoadDouble): (JSC::JSInterfaceJIT::emitJumpIfImmediateNumber): (JSC::JSInterfaceJIT::emitJumpIfNotImmediateNumber): (JSC::JSInterfaceJIT::emitLoadInt32):
  • jit/SpecializedThunkJIT.h: (JSC::SpecializedThunkJIT::loadDoubleArgument): (JSC::SpecializedThunkJIT::loadInt32Argument): (JSC::SpecializedThunkJIT::returnJSValue): (JSC::SpecializedThunkJIT::returnDouble): (JSC::SpecializedThunkJIT::finalize):
  • jit/ThunkGenerators.cpp: (JSC::sqrtThunkGenerator): (JSC::powThunkGenerator):
  • jit/ThunkGenerators.h:
  • runtime/Executable.h: (JSC::NativeExecutable::NativeExecutable):
  • runtime/JSFunction.cpp: (JSC::JSFunction::JSFunction):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JSInterfaceJIT.h

    r58283 r58469  
    6969        static const FPRegisterID fpRegT1 = X86Registers::xmm1;
    7070        static const FPRegisterID fpRegT2 = X86Registers::xmm2;
     71        static const FPRegisterID fpRegT3 = X86Registers::xmm3;
    7172#elif CPU(X86)
    7273        static const RegisterID returnValueRegister = X86Registers::eax;
     
    8788        static const FPRegisterID fpRegT1 = X86Registers::xmm1;
    8889        static const FPRegisterID fpRegT2 = X86Registers::xmm2;
     90        static const FPRegisterID fpRegT3 = X86Registers::xmm3;
    8991#elif CPU(ARM_THUMB2)
    9092        static const RegisterID returnValueRegister = ARMRegisters::r0;
     
    103105        static const FPRegisterID fpRegT1 = ARMRegisters::d1;
    104106        static const FPRegisterID fpRegT2 = ARMRegisters::d2;
     107        static const FPRegisterID fpRegT3 = ARMRegisters::d3;
    105108#elif CPU(ARM_TRADITIONAL)
    106109        static const RegisterID returnValueRegister = ARMRegisters::r0;
     
    127130        static const FPRegisterID fpRegT1 = ARMRegisters::d1;
    128131        static const FPRegisterID fpRegT2 = ARMRegisters::d2;
     132        static const FPRegisterID fpRegT3 = ARMRegisters::d3;
    129133#elif CPU(MIPS)
    130134        static const RegisterID returnValueRegister = MIPSRegisters::v0;
     
    149153        static const FPRegisterID fpRegT1 = MIPSRegisters::f6;
    150154        static const FPRegisterID fpRegT2 = MIPSRegisters::f8;
     155        static const FPRegisterID fpRegT2 = MIPSRegisters::f10;
    151156#else
    152157#error "JIT not supported on this platform."
     
    155160        inline Jump emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload);
    156161        inline Jump emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst);
     162        inline Jump emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch);
    157163
    158164#if USE(JSVALUE32_64)
     
    160166        inline Address tagFor(unsigned index, RegisterID base = callFrameRegister);
    161167#endif
     168
     169#if USE(JSVALUE32) || USE(JSVALUE64)
     170        Jump emitJumpIfImmediateNumber(RegisterID reg);
     171        Jump emitJumpIfNotImmediateNumber(RegisterID reg);
     172#endif
     173
    162174        inline Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
    163175        inline Address addressFor(unsigned index, RegisterID base = callFrameRegister);
    164176    };
    165    
     177
    166178#if USE(JSVALUE32_64)
    167179    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload)
     
    191203        return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
    192204    }
     205
     206    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
     207    {
     208        loadPtr(tagFor(virtualRegisterIndex), scratch);
     209        Jump isDouble = branch32(Below, scratch, Imm32(JSValue::LowestTag));
     210        Jump notInt = branch32(NotEqual, scratch, Imm32(JSValue::Int32Tag));
     211        loadPtr(payloadFor(virtualRegisterIndex), scratch);
     212        convertInt32ToDouble(scratch, dst);
     213        Jump done = jump();
     214        isDouble.link(this);
     215        loadDouble(addressFor(virtualRegisterIndex), dst);
     216        done.link(this);
     217        return notInt;
     218    }   
    193219#endif
    194220
    195221#if USE(JSVALUE64)
     222    ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfImmediateNumber(RegisterID reg)
     223    {
     224        return branchTestPtr(NonZero, reg, tagTypeNumberRegister);
     225    }
     226    ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotImmediateNumber(RegisterID reg)
     227    {
     228        return branchTestPtr(Zero, reg, tagTypeNumberRegister);
     229    }
    196230    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID dst)
    197231    {
     
    207241        return result;
    208242    }
     243
     244    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
     245    {
     246        loadPtr(addressFor(virtualRegisterIndex), scratch);
     247        Jump notNumber = emitJumpIfNotImmediateNumber(scratch);
     248        Jump notInt = branchPtr(Below, scratch, tagTypeNumberRegister);
     249        convertInt32ToDouble(scratch, dst);
     250        Jump done = jump();
     251        notInt.link(this);
     252        addPtr(tagTypeNumberRegister, scratch);
     253        movePtrToDouble(scratch, dst);
     254        done.link(this);
     255        return notNumber;
     256    }
     257
    209258#endif
    210259
     
    222271        rshift32(Imm32(JSImmediate::IntegerPayloadShift), dst);
    223272        return result;
    224     }   
     273    }
     274
     275    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned, FPRegisterID, RegisterID)
     276    {
     277        ASSERT_NOT_REACHED();
     278        return jump();
     279    }
    225280#endif
    226281
Note: See TracChangeset for help on using the changeset viewer.