Ignore:
Timestamp:
Jun 20, 2012, 6:38:49 PM (13 years ago)
Author:
[email protected]
Message:

DFG should optimize ResolveGlobal
https://bugs.webkit.org/show_bug.cgi?id=89617

Reviewed by Oliver Hunt.

This adds inlining of ResolveGlobal accesses that are known monomorphic. It also
adds the specific function optimization to ResolveGlobal, when it is inlined. And,
it makes internal functions act like specific functions, since that will be the
most common use-case of this optimization.

This is only a slighy speed-up (sub 1%), since we don't yet do the obvious thing
with this optimization, which is to completely inline common "globally resolved"
function and constructor calls, like "new Array()".

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::globalResolveInfoForBytecodeOffset):

  • bytecode/CodeBlock.h:

(CodeBlock):
(JSC::CodeBlock::numberOfGlobalResolveInfos):

  • bytecode/GlobalResolveInfo.h:

(JSC::getGlobalResolveInfoBytecodeOffset):
(JSC):

  • bytecode/ResolveGlobalStatus.cpp: Added.

(JSC):
(JSC::computeForStructure):
(JSC::computeForLLInt):
(JSC::ResolveGlobalStatus::computeFor):

  • bytecode/ResolveGlobalStatus.h: Added.

(JSC):
(ResolveGlobalStatus):
(JSC::ResolveGlobalStatus::ResolveGlobalStatus):
(JSC::ResolveGlobalStatus::state):
(JSC::ResolveGlobalStatus::isSet):
(JSC::ResolveGlobalStatus::operator!):
(JSC::ResolveGlobalStatus::isSimple):
(JSC::ResolveGlobalStatus::takesSlowPath):
(JSC::ResolveGlobalStatus::structure):
(JSC::ResolveGlobalStatus::offset):
(JSC::ResolveGlobalStatus::specificValue):

  • dfg/DFGByteCodeParser.cpp:

(ByteCodeParser):
(JSC::DFG::ByteCodeParser::handleGetByOffset):
(DFG):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::parseBlock):

  • runtime/JSObject.cpp:

(JSC::getCallableObjectSlow):
(JSC):
(JSC::JSObject::put):
(JSC::JSObject::putDirectVirtual):
(JSC::JSObject::putDirectAccessor):

  • runtime/JSObject.h:

(JSC):
(JSC::getCallableObject):
(JSC::JSObject::putOwnDataProperty):
(JSC::JSObject::putDirect):
(JSC::JSObject::putDirectWithoutTransition):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r120556 r120897  
    3636#include "MethodCallLinkStatus.h"
    3737#include "PutByIdStatus.h"
     38#include "ResolveGlobalStatus.h"
    3839#include <wtf/HashMap.h>
    3940#include <wtf/MathExtras.h>
     
    9596    // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
    9697    bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction);
     98    void handleGetByOffset(
     99        int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
     100        bool useInlineStorage, size_t offset);
    97101    void handleGetById(
    98102        int destinationOperand, SpeculatedType, NodeIndex base, unsigned identifierNumber,
     
    15681572}
    15691573
     1574void ByteCodeParser::handleGetByOffset(
     1575    int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
     1576    bool useInlineStorage, size_t offset)
     1577{
     1578    NodeIndex propertyStorage;
     1579    size_t offsetOffset;
     1580    if (useInlineStorage) {
     1581        propertyStorage = base;
     1582        ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
     1583        offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
     1584    } else {
     1585        propertyStorage = addToGraph(GetPropertyStorage, base);
     1586        offsetOffset = 0;
     1587    }
     1588    set(destinationOperand,
     1589        addToGraph(
     1590            GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction),
     1591            propertyStorage));
     1592       
     1593    StorageAccessData storageAccessData;
     1594    storageAccessData.offset = offset + offsetOffset;
     1595    storageAccessData.identifierNumber = identifierNumber;
     1596    m_graph.m_storageAccessData.append(storageAccessData);
     1597}
     1598
    15701599void ByteCodeParser::handleGetById(
    15711600    int destinationOperand, SpeculatedType prediction, NodeIndex base, unsigned identifierNumber,
     
    16211650    }
    16221651   
    1623     NodeIndex propertyStorage;
    1624     size_t offsetOffset;
    1625     if (useInlineStorage) {
    1626         propertyStorage = base;
    1627         ASSERT(!(sizeof(JSObject) % sizeof(EncodedJSValue)));
    1628         offsetOffset = sizeof(JSObject) / sizeof(EncodedJSValue);
    1629     } else {
    1630         propertyStorage = addToGraph(GetPropertyStorage, base);
    1631         offsetOffset = 0;
    1632     }
    1633     set(destinationOperand,
    1634         addToGraph(
    1635             GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction),
    1636             propertyStorage));
    1637        
    1638     StorageAccessData storageAccessData;
    1639     storageAccessData.offset = getByIdStatus.offset() + offsetOffset;
    1640     storageAccessData.identifierNumber = identifierNumber;
    1641     m_graph.m_storageAccessData.append(storageAccessData);
     1652    handleGetByOffset(
     1653        destinationOperand, prediction, base, identifierNumber, useInlineStorage,
     1654        getByIdStatus.offset());
    16421655}
    16431656
     
    26492662            SpeculatedType prediction = getPrediction();
    26502663           
     2664            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[
     2665                currentInstruction[2].u.operand];
     2666           
     2667            ResolveGlobalStatus status = ResolveGlobalStatus::computeFor(
     2668                m_inlineStackTop->m_profiledBlock, m_currentIndex,
     2669                m_codeBlock->identifier(identifierNumber));
     2670            if (status.isSimple()) {
     2671                ASSERT(status.structure());
     2672               
     2673                NodeIndex globalObject = addStructureTransitionCheck(
     2674                    m_inlineStackTop->m_codeBlock->globalObject(), status.structure());
     2675               
     2676                if (status.specificValue()) {
     2677                    ASSERT(status.specificValue().isCell());
     2678                   
     2679                    set(currentInstruction[1].u.operand,
     2680                        cellConstant(status.specificValue().asCell()));
     2681                } else {
     2682                    handleGetByOffset(
     2683                        currentInstruction[1].u.operand, prediction, globalObject,
     2684                        identifierNumber, status.structure()->isUsingInlineStorage(),
     2685                        status.offset());
     2686                }
     2687               
     2688                m_globalResolveNumber++; // Skip over the unused global resolve info.
     2689               
     2690                NEXT_OPCODE(op_resolve_global);
     2691            }
     2692           
    26512693            NodeIndex resolve = addToGraph(ResolveGlobal, OpInfo(m_graph.m_resolveGlobalData.size()), OpInfo(prediction));
    26522694            m_graph.m_resolveGlobalData.append(ResolveGlobalData());
    26532695            ResolveGlobalData& data = m_graph.m_resolveGlobalData.last();
    2654             data.identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[2].u.operand];
     2696            data.identifierNumber = identifierNumber;
    26552697            data.resolveInfoIndex = m_globalResolveNumber++;
    26562698            set(currentInstruction[1].u.operand, resolve);
Note: See TracChangeset for help on using the changeset viewer.