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/runtime/MathCommon.h

    r180258 r183358  
    3535namespace JSC {
    3636double JIT_OPERATION operationMathPow(double x, double y) WTF_INTERNAL;
     37
     38inline int clz32(uint32_t number)
     39{
     40#if COMPILER(GCC) || COMPILER(CLANG)
     41    int zeroCount = 32;
     42    if (number)
     43        zeroCount = __builtin_clz(number);
     44    return zeroCount;
     45#else
     46    int zeroCount = 0;
     47    for (int i = 31; i >= 0; i--) {
     48        if (!(number >> i))
     49            zeroCount++;
     50        else
     51            break;
     52    }
     53    return zeroCount;
     54#endif
     55}
     56
    3757}
    3858
Note: See TracChangeset for help on using the changeset viewer.