Ignore:
Timestamp:
May 7, 2010, 5:05:00 PM (15 years ago)
Author:
[email protected]
Message:

2010-05-07 Oliver Hunt <[email protected]>

Reviewed by Geoffrey Garen.

Optimize access to the global object from a function that uses eval
https://bugs.webkit.org/show_bug.cgi?id=38644

Add op_resolve_global_dynamic, a variant of op_resolve_global that
checks each node in the scope chain for dynamically inserted properties
and falls back to the normal resolve logic in that case.

  • JavaScriptCore.exp:
  • bytecode/CodeBlock.cpp: (JSC::isGlobalResolve): (JSC::CodeBlock::printStructures): (JSC::CodeBlock::dump): (JSC::CodeBlock::derefStructures):
  • bytecode/Opcode.h:
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::findScopedProperty):

Now take an additional reference parameter to used to indicate that
there were nodes that may gain dynamic properties

(JSC::BytecodeGenerator::emitResolve):
(JSC::BytecodeGenerator::emitResolveBase):
(JSC::BytecodeGenerator::emitResolveWithBase):

deal with additional argument to findScopedProperty

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp: (JSC::FunctionCallResolveNode::emitBytecode): (JSC::PostfixResolveNode::emitBytecode): (JSC::PrefixResolveNode::emitBytecode): (JSC::ReadModifyResolveNode::emitBytecode): (JSC::AssignResolveNode::emitBytecode):

These functions use findScopedProperty directly in order to
optimise lookup. They cannot trivially handle any degree of
dynamism in the lookup so we just give up in such case.

  • interpreter/Interpreter.cpp: (JSC::Interpreter::resolveGlobalDynamic): (JSC::Interpreter::execute): (JSC::Interpreter::privateExecute):
  • interpreter/Interpreter.h:
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases):
  • jit/JIT.h:
  • jit/JITOpcodes.cpp: (JSC::JIT::emit_op_resolve_global): (JSC::JIT::emit_op_resolve_global_dynamic): (JSC::JIT::emitSlow_op_resolve_global): (JSC::JIT::emitSlow_op_resolve_global_dynamic):

Happily resolve_global_dynamic can share the slow case!

  • jit/JITStubs.h: (JSC::):
  • runtime/JSActivation.cpp: (JSC::JSActivation::isDynamicScope):
  • runtime/JSActivation.h:
  • runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::isDynamicScope):
  • runtime/JSGlobalObject.h:
  • runtime/JSStaticScopeObject.cpp: (JSC::JSStaticScopeObject::isDynamicScope):
  • runtime/JSStaticScopeObject.h:
  • runtime/JSVariableObject.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r58907 r58986  
    994994}
    995995
    996 bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
     996bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, bool& requiresDynamicChecks, JSObject*& globalObject)
    997997{
    998998    // Cases where we cannot statically optimize the lookup.
     
    10101010
    10111011    size_t depth = 0;
    1012    
     1012    requiresDynamicChecks = false;
    10131013    ScopeChainIterator iter = m_scopeChain->begin();
    10141014    ScopeChainIterator end = m_scopeChain->end();
     
    10351035            return true;
    10361036        }
    1037         if (currentVariableObject->isDynamicScope())
     1037        bool scopeRequiresDynamicChecks = false;
     1038        if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
    10381039            break;
    1039     }
    1040 
     1040        requiresDynamicChecks |= scopeRequiresDynamicChecks;
     1041    }
    10411042    // Can't locate the property but we're able to avoid a few lookups.
    10421043    stackDepth = depth;
     
    10631064    int index = 0;
    10641065    JSObject* globalObject = 0;
    1065     if (!findScopedProperty(property, index, depth, false, globalObject) && !globalObject) {
     1066    bool requiresDynamicChecks = false;
     1067    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) && !globalObject) {
    10661068        // We can't optimise at all :-(
    10671069        emitOpcode(op_resolve);
     
    10911093        m_codeBlock->addGlobalResolveInstruction(instructions().size());
    10921094#endif
    1093         emitOpcode(op_resolve_global);
     1095        emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
    10941096        instructions().append(dst->index());
    10951097        instructions().append(globalObject);
     
    10971099        instructions().append(0);
    10981100        instructions().append(0);
     1101        if (requiresDynamicChecks)
     1102            instructions().append(depth);
     1103        return dst;
     1104    }
     1105
     1106    if (requiresDynamicChecks) {
     1107        // If we get here we have eval nested inside a |with| just give up
     1108        emitOpcode(op_resolve);
     1109        instructions().append(dst->index());
     1110        instructions().append(addConstant(property));
    10991111        return dst;
    11001112    }
     
    11521164    int index = 0;
    11531165    JSObject* globalObject = 0;
    1154     findScopedProperty(property, index, depth, false, globalObject);
    1155     if (!globalObject) {
     1166    bool requiresDynamicChecks = false;
     1167    findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
     1168    if (!globalObject || requiresDynamicChecks) {
    11561169        // We can't optimise at all :-(
    11571170        emitOpcode(op_resolve_base);
     
    11701183    int index = 0;
    11711184    JSObject* globalObject = 0;
    1172     if (!findScopedProperty(property, index, depth, false, globalObject) || !globalObject) {
     1185    bool requiresDynamicChecks = false;
     1186    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) {
    11731187        // We can't optimise at all :-(
    11741188        emitOpcode(op_resolve_with_base);
     
    12021216    m_codeBlock->addGlobalResolveInstruction(instructions().size());
    12031217#endif
    1204     emitOpcode(op_resolve_global);
     1218    emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
    12051219    instructions().append(propDst->index());
    12061220    instructions().append(globalObject);
     
    12081222    instructions().append(0);
    12091223    instructions().append(0);
     1224    if (requiresDynamicChecks)
     1225        instructions().append(depth);
    12101226    return baseDst;
    12111227}
Note: See TracChangeset for help on using the changeset viewer.