Skip to content
  • ggaren@apple.com's avatar
    Fast for-in enumeration: Cache JSPropertyNameIterator; cache JSStrings · 3806e0fa
    ggaren@apple.com authored
    in JSPropertyNameIterator; inline more code.
    
    Patch by Geoffrey Garen <ggaren@apple.com> on 2009-10-16
    Reviewed by Oliver Hunt.
    
    1.024x as fast on SunSpider (fasta: 1.43x as fast).
    
    * bytecode/CodeBlock.cpp:
    (JSC::CodeBlock::dump):
    * bytecode/Opcode.h:
    * bytecompiler/BytecodeGenerator.cpp:
    (JSC::BytecodeGenerator::emitGetPropertyNames):
    (JSC::BytecodeGenerator::emitNextPropertyName):
    * bytecompiler/BytecodeGenerator.h: Added a few extra operands to
    op_get_pnames and op_next_pname so that we can track iteration state
    in the register file instead of in the JSPropertyNameIterator. (To be
    cacheable, the JSPropertyNameIterator must be stateless.)
    
    * interpreter/Interpreter.cpp:
    (JSC::Interpreter::tryCachePutByID):
    (JSC::Interpreter::tryCacheGetByID): Updated for rename to
    "normalizePrototypeChain" and removal of "isCacheable". 
    
    (JSC::Interpreter::privateExecute): Updated for in-RegisterFile
    iteration state tracking.
    
    * jit/JIT.cpp:
    (JSC::JIT::privateCompileMainPass):
    * jit/JIT.h:
    * jit/JITOpcodes.cpp:
    (JSC::JIT::emit_op_get_pnames): Updated for in-RegisterFile
    iteration state tracking.
    
    (JSC::JIT::emit_op_next_pname): Inlined code generation for op_next_pname.
    
    * jit/JITStubs.cpp:
    (JSC::JITThunks::tryCachePutByID):
    (JSC::JITThunks::tryCacheGetByID): Updated for rename to
    "normalizePrototypeChain" and removal of "isCacheable". 
    
    (JSC::DEFINE_STUB_FUNCTION):
    * jit/JITStubs.h:
    (JSC::): Added has_property and to_object stubs. Removed op_next_pname
    stub, since has_property is all we need anymore.
    
    * parser/Nodes.cpp:
    (JSC::ForInNode::emitBytecode): Updated for in-RegisterFile
    iteration state tracking.
    
    * runtime/JSCell.h:
    * runtime/JSObject.cpp:
    (JSC::JSObject::getPropertyNames): Don't do caching at this layer
    anymore, since we don't create a JSPropertyNameIterator at this layer.
    
    * runtime/JSPropertyNameIterator.cpp:
    (JSC::JSPropertyNameIterator::create): Do do caching at this layer.
    (JSC::JSPropertyNameIterator::get):  Updated for in-RegisterFile
    iteration state tracking.
    (JSC::JSPropertyNameIterator::markChildren): Mark our JSStrings.
    
    * runtime/JSPropertyNameIterator.h:
    (JSC::JSPropertyNameIterator::size):
    (JSC::JSPropertyNameIterator::setCachedStructure):
    (JSC::JSPropertyNameIterator::cachedStructure):
    (JSC::JSPropertyNameIterator::setCachedPrototypeChain):
    (JSC::JSPropertyNameIterator::cachedPrototypeChain):
    (JSC::JSPropertyNameIterator::JSPropertyNameIterator):
    (JSC::Structure::setEnumerationCache): Don't store iteration state in
    a JSPropertyNameIterator. Do cache a JSPropertyNameIterator in a
    Structure.
    
    * runtime/JSValue.h:
    (JSC::asCell):
    * runtime/MarkStack.h: Make those mischievous #include gods happy.
    
    * runtime/ObjectConstructor.cpp:
    
    * runtime/Operations.h:
    (JSC::normalizePrototypeChain): Renamed countPrototypeChainEntriesAndCheckForProxies
    to normalizePrototypeChain, since it changes dictionary prototypes to
    non-dictionary objects.
    
    * runtime/PropertyNameArray.cpp:
    (JSC::PropertyNameArray::add):
    * runtime/PropertyNameArray.h:
    (JSC::PropertyNameArrayData::PropertyNameArrayData):
    (JSC::PropertyNameArray::data):
    (JSC::PropertyNameArray::size):
    (JSC::PropertyNameArray::begin):
    (JSC::PropertyNameArray::end): Simplified some code here to help with
    current and future refactoring.
    
    * runtime/Protect.h:
    * runtime/Structure.cpp:
    (JSC::Structure::~Structure):
    (JSC::Structure::addPropertyWithoutTransition):
    (JSC::Structure::removePropertyWithoutTransition): No need to clear
    the enumeration cache with adding / removing properties without
    transition. It is an error to add / remove properties without transition
    once an object has been observed, and we can ASSERT to catch that.
    
    * runtime/Structure.h:
    (JSC::Structure::enumerationCache): Changed the enumeration cache to
    hold a JSPropertyNameIterator.
    
    * runtime/StructureChain.cpp:
    * runtime/StructureChain.h:
    (JSC::StructureChain::head): Removed StructureChain::isCacheable because
    it was wrong-headed in two ways: (1) It gave up when a prototype was a
    dictionary, but instead we want un-dictionary heavily accessed
    prototypes; (2) It folded a test for hasDefaultGetPropertyNames() into
    a generic test for "cacheable-ness", but hasDefaultGetPropertyNames()
    is only releavant to for-in caching.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49717 268f45cc-cd09-0410-ab3c-d52691b4dbfc
    3806e0fa