[webkit-dev] Style proposal for branch style for macros

Filip Pizlo fpizlo at apple.com
Sat Apr 19 13:36:10 PDT 2014


Here are some examples.

Guarding a loop that does assertions:

    if (!ASSERT_DISABLED) {
        for (unsigned index = 0; index < m_generationInfo.size(); ++index) {
            GenerationInfo& info = m_generationInfo[index];
            RELEASE_ASSERT(!info.alive());
        }
    }

The one above comes from DFGSpeculativeJIT.cpp, and it is in a non-trivial method.  Using an #if here would obfuscate the control flow and make the method harder to maintain.  Arguably, a ASSERT would have been fine because the compiler "should" be smart enough to kill the loop if the ASSERT is a no-op.  I'm not sure all compilers would be smart enough, though - particularly if m_generationInfo is any kind of interesting collection class.

Guarding code in the JIT that emits an assertion:

    if (!ASSERT_DISABLED) {
        JITCompiler::Jump ok = m_jit.branch32(
            JITCompiler::GreaterThanOrEqual, allocatorGPR, TrustedImm32(0));
        m_jit.breakpoint();
        ok.link(&m_jit);
    }

The one above also comes from the DFG JIT.  We have lots of code like this.  The assertions are very useful but obviously we don't want them in a release build.  Using an #if would make the code harder to maintain.

Counterexample where we using an #if to guard an assertion in the JIT:

#if !ASSERT_DISABLED
        SpeculateCellOperand op1(this, node->child1());
        JITCompiler::Jump isOK = m_jit.branchStructurePtr(
            JITCompiler::Equal, 
            JITCompiler::Address(op1.gpr(), JSCell::structureIDOffset()), 
            node->structure());
        m_jit.breakpoint();
        isOK.link(&m_jit);
#else
        speculateCell(node->child1());
#endif

Code like this is harder to understand, especially if the code being guarded is longer than a page.  I don't think we should encourage this style, when it would have been clearer to do:

        if (!ASSERT_DISABLED) {
            SpeculateCellOperand op1(this, node->child1());
            JITCompiler::Jump isOK = m_jit.branchStructurePtr(
                JITCompiler::Equal, 
                JITCompiler::Address(op1.gpr(), JSCell::structureIDOffset()), 
                node->structure());
            m_jit.breakpoint();
            isOK.link(&m_jit);
        } else
            speculateCell(node->child1());

The point of coding conventions is to encourage clarity and common sense.  I don't think that #if's improve clarity.  I think what I'm proposing is a common sense rule that is easy to follow.  I trust everyone to know when a normal if statement would have been semantically equivalent to an #if statement.

-Phil


On April 19, 2014 at 1:22:23 PM, Geoffrey Garen (ggaren at apple.com) wrote:

Can you give a motivating example from WebKit?

Geoff

On Apr 19, 2014, at 1:09 PM, Filip Pizlo <fpizlo at apple.com> wrote:

Hey everyone,

When guarding code with macros that are always defined, such as ASSERT_DISABLED (it's always either 0 or 1), we have a choice between:

if (!ASSERT_DISABLED) {
    // do things
}

and:

#if !ASSERT_DISABLED
// do things
#endif

I'd like to propose that anytime the normal if would be semantically equivalent to the preprocessor #if, the normal if should be used.

We don't lose any compiler optimization, since even at -O0, the compiler will constant fold the normal if.  We do gain a lot of clarity, since the control flow of normal if statements is subject to proper indentation.

The "semantically equivalent" requirement still allows for #if to be used for thinngs like:

- Guarding the placement of fields in a class.
- Guarding the definitions of other macros (in the case of ASSERT_DISABLED, we define ASSERT in different ways guarded by #if's)
- Guarding the definition/declaration/inclusion of entire functions, classes, and other top-level constructs.

Thoughts?

-Phil

_______________________________________________
webkit-dev mailing list
webkit-dev at lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-dev/attachments/20140419/1d52f772/attachment.html>


More information about the webkit-dev mailing list