Ignore:
Timestamp:
May 10, 2012, 11:40:29 AM (13 years ago)
Author:
[email protected]
Message:

Cache inheritorID on JSFunction
https://bugs.webkit.org/show_bug.cgi?id=85853

Reviewed by Geoff Garen & Filip Pizlo.

An object's prototype is indicated via its structure. To create an otherwise
empty object with object A as its prototype, we require a structure with its
prototype set to point to A. We wish to use this same structure for all empty
objects created with a prototype of A, so we presently store this structure as
a property of A, known as the inheritorID.

When a function F is invoked as a constructor, where F has a property 'prototype'
set to point to A, in order to create the 'this' value for the constructor to
use the following steps are taken:

  • the 'prototype' proptery of F is read, via a regular Get access.
  • the inheritorID internal property of the prototype is read.
  • a new, empty object is constructed with its structure set to point to inheritorID.

There are two drawbacks to the current approach:

  • it requires that every object has an inheritorID field.
  • it requires a Get access on every constructor call to access the 'prototype' property.

Instead, switch to caching a copy of the inheritorID on the function. Constructor
calls now only need read the internal property from the callee, saving a Get.
This also means that JSObject::m_inheritorID is no longer commonly read, and in a
future patch we can move to storing this in a more memory efficient fashion.

(JSC::CodeBlock::dump):

  • bytecode/Opcode.h:

(JSC):
(JSC::padOpcodeName):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGNodeType.h:

(DFG):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::privateExecute):

  • jit/JITInlineMethods.h:

(JSC::JIT::emitAllocateJSFunction):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_create_this):
(JSC::JIT::emitSlow_op_create_this):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_create_this):
(JSC::JIT::emitSlow_op_create_this):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/JSFunction.cpp:

(JSC::JSFunction::JSFunction):
(JSC::JSFunction::cacheInheritorID):
(JSC):
(JSC::JSFunction::put):
(JSC::JSFunction::defineOwnProperty):

  • runtime/JSFunction.h:

(JSC::JSFunction::cachedInheritorID):
(JSFunction):
(JSC::JSFunction::offsetOfCachedInheritorID):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r112285 r116670  
    113113}
    114114
     115Structure* JSFunction::cacheInheritorID(ExecState* exec)
     116{
     117    JSValue prototype = get(exec, exec->globalData().propertyNames->prototype);
     118    if (prototype.isObject())
     119        m_cachedInheritorID.set(exec->globalData(), this, asObject(prototype)->inheritorID(exec->globalData()));
     120    else
     121        m_cachedInheritorID.set(exec->globalData(), this, globalObject()->emptyObjectStructure());
     122    return m_cachedInheritorID.get();
     123}
     124
    115125const UString& JSFunction::name(ExecState* exec)
    116126{
     
    333343        PropertySlot slot;
    334344        thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
     345        thisObject->m_cachedInheritorID.clear();
    335346    }
    336347    if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) {
     
    373384        PropertySlot slot;
    374385        thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
     386        thisObject->m_cachedInheritorID.clear();
    375387        return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
    376388    }
Note: See TracChangeset for help on using the changeset viewer.