Ignore:
Timestamp:
Sep 11, 2012, 1:00:31 PM (13 years ago)
Author:
[email protected]
Message:

LLInt should optimize and profile array length accesses
https://bugs.webkit.org/show_bug.cgi?id=96417

Reviewed by Oliver Hunt.

This fixes the following hole in our array profiling strategy, where the array
is large (more than 1000 elements):

for (var i = 0; i < array.length; ++i) ...

The peeled use of array.length (in the array prologue) will execute only once
before DFG optimization kicks in from the loop's OSR point. Since it executed
only once, it executed in the LLInt. And prior to this patch, the LLInt did
not profile array.length accesses - so the DFG will assume, based on the lack
of profiling, that the access is in fact not an access to the JSArray length
property. That could then impede our ability to hoist the array structure
check, and may make us pessimistic in other ways as well, since the generic
GetById used for the array length access will be viewed as a side-effecting
operation.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::printGetByIdCacheStatus):
(JSC::CodeBlock::finalizeUnconditionally):

  • bytecode/GetByIdStatus.cpp:

(JSC::GetByIdStatus::computeFromLLInt):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCapabilities.h:

(JSC::DFG::canCompileOpcode):

  • dfg/DFGFixupPhase.cpp:

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

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r128096 r128219  
    292292   
    293293#if ENABLE(LLINT)
    294     Structure* structure = instruction[4].u.structure.get();
    295     dataLog(" llint(");
    296     dumpStructure("struct", exec, structure, ident);
    297     dataLog(")");
     294    if (exec->interpreter()->getOpcodeID(instruction[0].u.opcode) == op_get_array_length)
     295        dataLog(" llint(array_length)");
     296    else {
     297        Structure* structure = instruction[4].u.structure.get();
     298        dataLog(" llint(");
     299        dumpStructure("struct", exec, structure, ident);
     300        dataLog(")");
     301    }
    298302#endif
    299303
     
    20822086                curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
    20832087                break;
     2088            case op_get_array_length:
     2089                break;
    20842090            default:
    20852091                ASSERT_NOT_REACHED();
Note: See TracChangeset for help on using the changeset viewer.