Changeset 36480 in webkit for trunk/JavaScriptCore/VM/Machine.cpp


Ignore:
Timestamp:
Sep 15, 2008, 10:53:15 PM (17 years ago)
Author:
[email protected]
Message:

Bug 20874: op_resolve does not do any form of caching
<https://bugs.webkit.org/show_bug.cgi?id=20874>

Reviewed by Cameron Zwarich

This patch adds an op_resolve_global opcode to handle (and cache)
property lookup we can statically determine must occur on the global
object (if at all).

3% progression on sunspider, 3.2x improvement to bitops-bitwise-and, and
10% in math-partial-sums

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/Machine.cpp

    r36475 r36480  
    328328        }
    329329    } while (++iter != end);
     330    exceptionValue = createUndefinedVariableError(exec, ident, vPC, codeBlock);
     331    return false;
     332}
     333
     334static bool NEVER_INLINE resolveGlobal(ExecState* exec, Instruction* vPC, Register* r, CodeBlock* codeBlock, JSValue*& exceptionValue)
     335{
     336    int dst = (vPC + 1)->u.operand;
     337    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell);
     338    ASSERT(globalObject->isGlobalObject());
     339    int property = (vPC + 3)->u.operand;
     340    StructureID* structureID = (vPC + 4)->u.structureID;
     341    int offset = (vPC + 5)->u.operand;
     342
     343    if (structureID == globalObject->structureID()) {
     344        r[dst] = globalObject->getDirectOffset(offset);
     345        return true;
     346    }
     347
     348    Identifier& ident = codeBlock->identifiers[property];
     349    PropertySlot slot(globalObject);
     350    if (globalObject->getPropertySlot(exec, ident, slot)) {
     351        JSValue* result = slot.getValue(exec, ident);
     352        if (slot.isCacheable()) {
     353            if (vPC[4].u.structureID)
     354                vPC[4].u.structureID->deref();
     355            globalObject->structureID()->ref();
     356            vPC[4] = globalObject->structureID();
     357            vPC[5] = slot.cachedOffset();
     358            r[dst] = result;
     359            return true;
     360        }
     361
     362        exceptionValue = exec->exception();
     363        if (exceptionValue)
     364            return false;
     365        r[dst] = result;
     366        return true;
     367    }
     368
    330369    exceptionValue = createUndefinedVariableError(exec, ident, vPC, codeBlock);
    331370    return false;
     
    22222261        NEXT_OPCODE;
    22232262    }
     2263    BEGIN_OPCODE(op_resolve_global) {
     2264        /* resolve_skip dst(r) globalObject(c) property(id) structureID(sID) offset(n)
     2265         
     2266           Performs a dynamic property lookup for the given property, on the provided
     2267           global object.  If structureID matches the StructureID of the global then perform
     2268           a fast lookup using the case offset, otherwise fall back to a full resolve and
     2269           cache the new structureID and offset
     2270         */
     2271        if (UNLIKELY(!resolveGlobal(exec, vPC, r,  codeBlock, exceptionValue)))
     2272            goto vm_throw;
     2273       
     2274        vPC += 6;
     2275       
     2276        NEXT_OPCODE;
     2277    }
    22242278    BEGIN_OPCODE(op_get_global_var) {
    2225         /* get_global_var dst(r) index(n)
     2279        /* get_global_var dst(r) globalObject(c) index(n)
    22262280
    22272281           Gets the global var at global slot index and places it in register dst.
     
    47814835}
    47824836
     4837JSValue* Machine::cti_op_resolve_global(CTI_ARGS)
     4838{
     4839    ExecState* exec = ARG_exec;
     4840    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(ARG_src1);
     4841    Identifier& ident = *ARG_id2;
     4842    Instruction* vPC = ARG_instr3;
     4843    ASSERT(globalObject->isGlobalObject());
     4844
     4845    PropertySlot slot(globalObject);
     4846    if (globalObject->getPropertySlot(exec, ident, slot)) {
     4847        JSValue* result = slot.getValue(exec, ident);
     4848        if (slot.isCacheable()) {
     4849            if (vPC[4].u.structureID)
     4850                vPC[4].u.structureID->deref();
     4851            globalObject->structureID()->ref();
     4852            vPC[4] = globalObject->structureID();
     4853            vPC[5] = slot.cachedOffset();
     4854            return result;
     4855        }
     4856
     4857        VM_CHECK_EXCEPTION_AT_END();
     4858        return result;
     4859    }
     4860   
     4861    exec->setException(createUndefinedVariableError(exec, ident, vPC, ARG_codeBlock));
     4862   
     4863    VM_CHECK_EXCEPTION_AT_END();
     4864    return 0;
     4865}
     4866
    47834867JSValue* Machine::cti_op_div(CTI_ARGS)
    47844868{
Note: See TracChangeset for help on using the changeset viewer.