Ignore:
Timestamp:
Apr 26, 2015, 12:55:18 PM (10 years ago)
Author:
[email protected]
Message:

[JSC] Implement Math.clz32(), remove Number.clz()
https://bugs.webkit.org/show_bug.cgi?id=144205

Reviewed by Michael Saboff.

Source/JavaScriptCore:

This patch adds the ES6 function Math.clz32(), and remove the non-standard
Number.clz(). Number.clz() probably came from an older draft.

The new function has a corresponding instrinsic: Clz32Intrinsic,
and a corresponding DFG node: ArithClz32, optimized all the way to LLVM.

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::countLeadingZeros32):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::bsr_rr):
The x86 assembler did not have countLeadingZeros32() because there is
no native CLZ instruction on that architecture.

I have added the version with bsr + branches for the case of zero.
An other popular version uses cmov to handle the case of zero. I kept
it simple since the Assembler has no support for cmov.

It is unlikely to matter much. If the code is hot enough, LLVM picks
something good based on the surrounding code.

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
Constant handling + effect propagation. The node only produces integer (between 0 and 32).

  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::propagate):
Thanks to the definition of toUint32(), we can ignore plenty of details
from doubles.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsic):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGNodeType.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithClz32):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLIntrinsicRepository.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileArithClz32):

  • ftl/FTLOutput.h:

(JSC::FTL::Output::ctlz32):

  • jit/ThunkGenerators.cpp:

(JSC::clz32ThunkGenerator):

  • jit/ThunkGenerators.h:
  • runtime/Intrinsic.h:
  • runtime/MathCommon.h:

(JSC::clz32):
Fun fact: InstCombine does not recognize this pattern to eliminate
the branch which makes our FTL version better than the C version.

  • runtime/MathObject.cpp:

(JSC::MathObject::finishCreation):
(JSC::mathProtoFuncClz32):

  • runtime/NumberPrototype.cpp:

(JSC::clz): Deleted.
(JSC::numberProtoFuncClz): Deleted.

  • runtime/VM.cpp:

(JSC::thunkGeneratorForIntrinsic):

  • tests/stress/math-clz32-basics.js: Added.

(mathClz32OnInteger):
(testMathClz32OnIntegers):
(verifyMathClz32OnIntegerWithOtherTypes):
(mathClz32OnDouble):
(testMathClz32OnDoubles):
(verifyMathClz32OnDoublesWithOtherTypes):
(mathClz32NoArguments):
(mathClz32TooManyArguments):
(testMathClz32OnConstants):
(mathClz32StructTransition):
(Math.clz32):

LayoutTests:

Basic conformance tests.

  • js/Object-getOwnPropertyNames-expected.txt:
  • js/math-clz32-expected.txt: Added.
  • js/math-clz32.html: Renamed from LayoutTests/js/number-clz.html.
  • js/number-clz-expected.txt: Removed.
  • js/script-tests/Object-getOwnPropertyNames.js:
  • js/script-tests/math-clz32.js: Added.

(objectConvertToString.toString):
(objectRecordToStringCall.toString):
(objectThrowOnToString.toString):
(objectWithValueOf.valueOf):
(objectThrowOnValueOf.valueOf):
(objectThrowOnValueOf.toString):
(objectRecordValueOfCall.valueOf):
(objectRecordConversionCalls.toString):
(objectRecordConversionCalls.valueOf):

  • js/script-tests/number-clz.js: Removed.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r182098 r183358  
    182182        move(src, dest);
    183183        and32(imm, dest);
     184    }
     185
     186    void countLeadingZeros32(RegisterID src, RegisterID dst)
     187    {
     188        m_assembler.bsr_rr(src, dst);
     189        Jump srcIsNonZero = m_assembler.jCC(x86Condition(NonZero));
     190        move(TrustedImm32(32), dst);
     191
     192        Jump skipNonZeroCase = jump();
     193        srcIsNonZero.link(this);
     194        xor32(TrustedImm32(0x1f), dst);
     195        skipNonZeroCase.link(this);
    184196    }
    185197
Note: See TracChangeset for help on using the changeset viewer.