⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 181891 in webkit


Ignore:
Timestamp:
Mar 24, 2015, 3:05:21 AM (11 years ago)
Author:
msaboff@apple.com
Message:

REGRESSION (172175-172177): Change in for...in processing causes properties added in loop to be enumerated
https://bugs.webkit.org/show_bug.cgi?id=142856

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Refactored the way the for .. in enumeration over objects is done. We used to make three C++ calls to
get info for three loops to iterate over indexed properties, structure properties and other properties,
respectively. We still have the three loops, but now we make one C++ call to get all the info needed
for all loops before we exectue any enumeration.

The JSPropertyEnumerator has a count of the indexed properties and a list of named properties.
The named properties are one list, with structured properties in the range [0,m_endStructurePropertyIndex)
and the generic properties in the range [m_endStructurePropertyIndex, m_endGenericPropertyIndex);

Eliminated the bytecodes op_get_structure_property_enumerator, op_get_generic_property_enumerator and
op_next_enumerator_pname.
Added the bytecodes op_get_property_enumerator, op_enumerator_structure_pname and op_enumerator_generic_pname.
The bytecodes op_enumerator_structure_pname and op_enumerator_generic_pname are similar except for what
end value we stop iterating on.

Made corresponding node changes to the DFG and FTL for the bytecode changes.

  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitGetPropertyEnumerator):
(JSC::BytecodeGenerator::emitEnumeratorStructurePropertyName):
(JSC::BytecodeGenerator::emitEnumeratorGenericPropertyName):
(JSC::BytecodeGenerator::emitGetStructurePropertyEnumerator): Deleted.
(JSC::BytecodeGenerator::emitGetGenericPropertyEnumerator): Deleted.
(JSC::BytecodeGenerator::emitNextEnumeratorPropertyName): Deleted.

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::ForInNode::emitMultiLoopBytecode):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

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

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

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

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

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumerableLength):
(JSC::FTL::LowerDFGToLLVM::compileGetPropertyEnumerator):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorStructurePname):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorGenericPname):
(JSC::FTL::LowerDFGToLLVM::compileGetStructurePropertyEnumerator): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetGenericPropertyEnumerator): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname): Deleted.

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • jit/JIT.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_enumerator_structure_pname):
(JSC::JIT::emit_op_enumerator_generic_pname):
(JSC::JIT::emit_op_get_property_enumerator):
(JSC::JIT::emit_op_next_enumerator_pname): Deleted.
(JSC::JIT::emit_op_get_structure_property_enumerator): Deleted.
(JSC::JIT::emit_op_get_generic_property_enumerator): Deleted.

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_enumerator_structure_pname):
(JSC::JIT::emit_op_enumerator_generic_pname):
(JSC::JIT::emit_op_next_enumerator_pname): Deleted.

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • llint/LowLevelInterpreter.asm:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:
  • runtime/JSPropertyNameEnumerator.cpp:

(JSC::JSPropertyNameEnumerator::create):
(JSC::JSPropertyNameEnumerator::finishCreation):

  • runtime/JSPropertyNameEnumerator.h:

(JSC::JSPropertyNameEnumerator::indexedLength):
(JSC::JSPropertyNameEnumerator::endStructurePropertyIndex):
(JSC::JSPropertyNameEnumerator::endGenericPropertyIndex):
(JSC::JSPropertyNameEnumerator::indexedLengthOffset):
(JSC::JSPropertyNameEnumerator::endStructurePropertyIndexOffset):
(JSC::JSPropertyNameEnumerator::endGenericPropertyIndexOffset):
(JSC::JSPropertyNameEnumerator::cachedInlineCapacityOffset):
(JSC::propertyNameEnumerator):
(JSC::JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset): Deleted.
(JSC::structurePropertyNameEnumerator): Deleted.
(JSC::genericPropertyNameEnumerator): Deleted.

  • runtime/Structure.cpp:

(JSC::Structure::setCachedPropertyNameEnumerator):
(JSC::Structure::cachedPropertyNameEnumerator):
(JSC::Structure::canCachePropertyNameEnumerator):
(JSC::Structure::setCachedStructurePropertyNameEnumerator): Deleted.
(JSC::Structure::cachedStructurePropertyNameEnumerator): Deleted.
(JSC::Structure::setCachedGenericPropertyNameEnumerator): Deleted.
(JSC::Structure::cachedGenericPropertyNameEnumerator): Deleted.
(JSC::Structure::canCacheStructurePropertyNameEnumerator): Deleted.
(JSC::Structure::canCacheGenericPropertyNameEnumerator): Deleted.

  • runtime/Structure.h:
  • runtime/StructureRareData.cpp:

(JSC::StructureRareData::visitChildren):
(JSC::StructureRareData::cachedPropertyNameEnumerator):
(JSC::StructureRareData::setCachedPropertyNameEnumerator):
(JSC::StructureRareData::cachedStructurePropertyNameEnumerator): Deleted.
(JSC::StructureRareData::setCachedStructurePropertyNameEnumerator): Deleted.
(JSC::StructureRareData::cachedGenericPropertyNameEnumerator): Deleted.
(JSC::StructureRareData::setCachedGenericPropertyNameEnumerator): Deleted.

  • runtime/StructureRareData.h:
  • tests/stress/for-in-delete-during-iteration.js:

LayoutTests:

New tests and rebased one test.

  • js/for-in-modify-in-loop-expected.txt: Added.
  • js/for-in-modify-in-loop.html: Added.
  • js/script-tests/for-in-modify-in-loop.js: Added.

(haveSameProperties):
(each):
(testAdd):
(testAddDelete):

  • http/tests/security/cross-frame-access-enumeration-expected.txt: Rebased.
Location:
trunk
Files:
3 added
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r181889 r181891  
     12015-03-24  Michael Saboff  <msaboff@apple.com>
     2
     3        REGRESSION (172175-172177): Change in for...in processing causes properties added in loop to be enumerated
     4        https://bugs.webkit.org/show_bug.cgi?id=142856
     5
     6        Reviewed by Filip Pizlo.
     7
     8        New tests and rebased one test.
     9
     10        * js/for-in-modify-in-loop-expected.txt: Added.
     11        * js/for-in-modify-in-loop.html: Added.
     12        * js/script-tests/for-in-modify-in-loop.js: Added.
     13        (haveSameProperties):
     14        (each):
     15        (testAdd):
     16        (testAddDelete):
     17        * http/tests/security/cross-frame-access-enumeration-expected.txt: Rebased.
     18
    1192015-03-24  Saam Barati  <saambarati1@gmail.com>
    220
  • trunk/LayoutTests/http/tests/security/cross-frame-access-enumeration-expected.txt

    r178527 r181891  
    88CONSOLE MESSAGE: line 75: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
    99CONSOLE MESSAGE: line 82: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
     10CONSOLE MESSAGE: line 29: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
    1011CONSOLE MESSAGE: line 29: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
    1112CONSOLE MESSAGE: line 29: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
  • trunk/Source/JavaScriptCore/ChangeLog

    r181890 r181891  
     12015-03-24  Michael Saboff  <msaboff@apple.com>
     2
     3        REGRESSION (172175-172177): Change in for...in processing causes properties added in loop to be enumerated
     4        https://bugs.webkit.org/show_bug.cgi?id=142856
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Refactored the way the for .. in enumeration over objects is done.  We used to make three C++ calls to
     9        get info for three loops to iterate over indexed properties, structure properties and other properties,
     10        respectively.  We still have the three loops, but now we make one C++ call to get all the info needed
     11        for all loops before we exectue any enumeration.
     12
     13        The JSPropertyEnumerator has a count of the indexed properties and a list of named properties.
     14        The named properties are one list, with structured properties in the range [0,m_endStructurePropertyIndex)
     15        and the generic properties in the range [m_endStructurePropertyIndex, m_endGenericPropertyIndex);
     16
     17        Eliminated the bytecodes op_get_structure_property_enumerator, op_get_generic_property_enumerator and
     18        op_next_enumerator_pname.
     19        Added the bytecodes op_get_property_enumerator, op_enumerator_structure_pname and op_enumerator_generic_pname.
     20        The bytecodes op_enumerator_structure_pname and op_enumerator_generic_pname are similar except for what
     21        end value we stop iterating on.
     22
     23        Made corresponding node changes to the DFG and FTL for the bytecode changes.
     24
     25        * bytecode/BytecodeList.json:
     26        * bytecode/BytecodeUseDef.h:
     27        (JSC::computeUsesForBytecodeOffset):
     28        (JSC::computeDefsForBytecodeOffset):
     29        * bytecode/CodeBlock.cpp:
     30        (JSC::CodeBlock::dumpBytecode):
     31        * bytecompiler/BytecodeGenerator.cpp:
     32        (JSC::BytecodeGenerator::emitGetPropertyEnumerator):
     33        (JSC::BytecodeGenerator::emitEnumeratorStructurePropertyName):
     34        (JSC::BytecodeGenerator::emitEnumeratorGenericPropertyName):
     35        (JSC::BytecodeGenerator::emitGetStructurePropertyEnumerator): Deleted.
     36        (JSC::BytecodeGenerator::emitGetGenericPropertyEnumerator): Deleted.
     37        (JSC::BytecodeGenerator::emitNextEnumeratorPropertyName): Deleted.
     38        * bytecompiler/BytecodeGenerator.h:
     39        * bytecompiler/NodesCodegen.cpp:
     40        (JSC::ForInNode::emitMultiLoopBytecode):
     41        * dfg/DFGAbstractInterpreterInlines.h:
     42        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     43        * dfg/DFGByteCodeParser.cpp:
     44        (JSC::DFG::ByteCodeParser::parseBlock):
     45        * dfg/DFGCapabilities.cpp:
     46        (JSC::DFG::capabilityLevel):
     47        * dfg/DFGClobberize.h:
     48        (JSC::DFG::clobberize):
     49        * dfg/DFGDoesGC.cpp:
     50        (JSC::DFG::doesGC):
     51        * dfg/DFGFixupPhase.cpp:
     52        (JSC::DFG::FixupPhase::fixupNode):
     53        * dfg/DFGNodeType.h:
     54        * dfg/DFGPredictionPropagationPhase.cpp:
     55        (JSC::DFG::PredictionPropagationPhase::propagate):
     56        * dfg/DFGSafeToExecute.h:
     57        (JSC::DFG::safeToExecute):
     58        * dfg/DFGSpeculativeJIT32_64.cpp:
     59        (JSC::DFG::SpeculativeJIT::compile):
     60        * dfg/DFGSpeculativeJIT64.cpp:
     61        (JSC::DFG::SpeculativeJIT::compile):
     62        * ftl/FTLAbstractHeapRepository.h:
     63        * ftl/FTLCapabilities.cpp:
     64        (JSC::FTL::canCompile):
     65        * ftl/FTLLowerDFGToLLVM.cpp:
     66        (JSC::FTL::LowerDFGToLLVM::compileNode):
     67        (JSC::FTL::LowerDFGToLLVM::compileGetEnumerableLength):
     68        (JSC::FTL::LowerDFGToLLVM::compileGetPropertyEnumerator):
     69        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorStructurePname):
     70        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorGenericPname):
     71        (JSC::FTL::LowerDFGToLLVM::compileGetStructurePropertyEnumerator): Deleted.
     72        (JSC::FTL::LowerDFGToLLVM::compileGetGenericPropertyEnumerator): Deleted.
     73        (JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname): Deleted.
     74        * jit/JIT.cpp:
     75        (JSC::JIT::privateCompileMainPass):
     76        * jit/JIT.h:
     77        * jit/JITOpcodes.cpp:
     78        (JSC::JIT::emit_op_enumerator_structure_pname):
     79        (JSC::JIT::emit_op_enumerator_generic_pname):
     80        (JSC::JIT::emit_op_get_property_enumerator):
     81        (JSC::JIT::emit_op_next_enumerator_pname): Deleted.
     82        (JSC::JIT::emit_op_get_structure_property_enumerator): Deleted.
     83        (JSC::JIT::emit_op_get_generic_property_enumerator): Deleted.
     84        * jit/JITOpcodes32_64.cpp:
     85        (JSC::JIT::emit_op_enumerator_structure_pname):
     86        (JSC::JIT::emit_op_enumerator_generic_pname):
     87        (JSC::JIT::emit_op_next_enumerator_pname): Deleted.
     88        * jit/JITOperations.cpp:
     89        * jit/JITOperations.h:
     90        * llint/LowLevelInterpreter.asm:
     91        * runtime/CommonSlowPaths.cpp:
     92        (JSC::SLOW_PATH_DECL):
     93        * runtime/CommonSlowPaths.h:
     94        * runtime/JSPropertyNameEnumerator.cpp:
     95        (JSC::JSPropertyNameEnumerator::create):
     96        (JSC::JSPropertyNameEnumerator::finishCreation):
     97        * runtime/JSPropertyNameEnumerator.h:
     98        (JSC::JSPropertyNameEnumerator::indexedLength):
     99        (JSC::JSPropertyNameEnumerator::endStructurePropertyIndex):
     100        (JSC::JSPropertyNameEnumerator::endGenericPropertyIndex):
     101        (JSC::JSPropertyNameEnumerator::indexedLengthOffset):
     102        (JSC::JSPropertyNameEnumerator::endStructurePropertyIndexOffset):
     103        (JSC::JSPropertyNameEnumerator::endGenericPropertyIndexOffset):
     104        (JSC::JSPropertyNameEnumerator::cachedInlineCapacityOffset):
     105        (JSC::propertyNameEnumerator):
     106        (JSC::JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset): Deleted.
     107        (JSC::structurePropertyNameEnumerator): Deleted.
     108        (JSC::genericPropertyNameEnumerator): Deleted.
     109        * runtime/Structure.cpp:
     110        (JSC::Structure::setCachedPropertyNameEnumerator):
     111        (JSC::Structure::cachedPropertyNameEnumerator):
     112        (JSC::Structure::canCachePropertyNameEnumerator):
     113        (JSC::Structure::setCachedStructurePropertyNameEnumerator): Deleted.
     114        (JSC::Structure::cachedStructurePropertyNameEnumerator): Deleted.
     115        (JSC::Structure::setCachedGenericPropertyNameEnumerator): Deleted.
     116        (JSC::Structure::cachedGenericPropertyNameEnumerator): Deleted.
     117        (JSC::Structure::canCacheStructurePropertyNameEnumerator): Deleted.
     118        (JSC::Structure::canCacheGenericPropertyNameEnumerator): Deleted.
     119        * runtime/Structure.h:
     120        * runtime/StructureRareData.cpp:
     121        (JSC::StructureRareData::visitChildren):
     122        (JSC::StructureRareData::cachedPropertyNameEnumerator):
     123        (JSC::StructureRareData::setCachedPropertyNameEnumerator):
     124        (JSC::StructureRareData::cachedStructurePropertyNameEnumerator): Deleted.
     125        (JSC::StructureRareData::setCachedStructurePropertyNameEnumerator): Deleted.
     126        (JSC::StructureRareData::cachedGenericPropertyNameEnumerator): Deleted.
     127        (JSC::StructureRareData::setCachedGenericPropertyNameEnumerator): Deleted.
     128        * runtime/StructureRareData.h:
     129        * tests/stress/for-in-delete-during-iteration.js:
     130
    11312015-03-24  Michael Saboff  <msaboff@apple.com>
    2132
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r181466 r181891  
    126126            { "name" : "op_has_generic_property", "length" : 4 },
    127127            { "name" : "op_get_direct_pname", "length" : 7 },
    128             { "name" : "op_get_structure_property_enumerator", "length" : 4 },
    129             { "name" : "op_get_generic_property_enumerator", "length" : 5 },
    130             { "name" : "op_next_enumerator_pname", "length" : 4 },
     128            { "name" : "op_get_property_enumerator", "length" : 3 },
     129            { "name" : "op_enumerator_structure_pname", "length" : 4 },
     130            { "name" : "op_enumerator_generic_pname", "length" : 4 },
    131131            { "name" : "op_to_index_string", "length" : 3 }
    132132        ]
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r181467 r181891  
    114114    }
    115115    case op_create_lexical_environment:
     116    case op_get_property_enumerator:
    116117    case op_get_enumerable_length:
    117118    case op_new_func_exp:
     
    150151    }
    151152    case op_has_generic_property:
    152     case op_get_structure_property_enumerator:
    153153    case op_has_indexed_property:
    154     case op_next_enumerator_pname:
     154    case op_enumerator_structure_pname:
     155    case op_enumerator_generic_pname:
    155156    case op_get_by_val:
    156157    case op_in:
     
    183184    case op_has_structure_property:
    184185    case op_get_argument_by_val:
    185     case op_get_generic_property_enumerator:
    186186    case op_construct_varargs:
    187187    case op_call_varargs: {
     
    292292    // These all have a single destination for the first argument.
    293293    case op_to_index_string:
    294     case op_get_generic_property_enumerator:
    295294    case op_get_enumerable_length:
    296295    case op_has_indexed_property:
     
    298297    case op_has_generic_property:
    299298    case op_get_direct_pname:
    300     case op_get_structure_property_enumerator:
    301     case op_next_enumerator_pname:
     299    case op_get_property_enumerator:
     300    case op_enumerator_structure_pname:
     301    case op_enumerator_generic_pname:
    302302    case op_pop_scope:
    303303    case op_push_name_scope:
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r181673 r181891  
    14091409
    14101410        }
    1411         case op_get_structure_property_enumerator: {
     1411        case op_get_property_enumerator: {
    14121412            int dst = it[1].u.operand;
    14131413            int base = it[2].u.operand;
    1414             printLocationAndOp(out, exec, location, it, "op_get_structure_property_enumerator");
     1414            printLocationAndOp(out, exec, location, it, "op_get_property_enumerator");
    14151415            out.printf("%s, %s", registerName(dst).data(), registerName(base).data());
    1416             it += OPCODE_LENGTH(op_get_structure_property_enumerator) - 1;
    1417             break;
    1418         }
    1419         case op_get_generic_property_enumerator: {
    1420             int dst = it[1].u.operand;
    1421             int base = it[2].u.operand;
    1422             int length = it[3].u.operand;
    1423             int structureEnumerator = it[4].u.operand;
    1424             printLocationAndOp(out, exec, location, it, "op_get_generic_property_enumerator");
    1425             out.printf("%s, %s, %s, %s", registerName(dst).data(), registerName(base).data(), registerName(length).data(), registerName(structureEnumerator).data());
    1426             it += OPCODE_LENGTH(op_get_generic_property_enumerator) - 1;
    1427             break;
    1428         }
    1429         case op_next_enumerator_pname: {
     1416            it += OPCODE_LENGTH(op_get_property_enumerator) - 1;
     1417            break;
     1418        }
     1419        case op_enumerator_structure_pname: {
    14301420            int dst = it[1].u.operand;
    14311421            int enumerator = it[2].u.operand;
    14321422            int index = it[3].u.operand;
    1433             printLocationAndOp(out, exec, location, it, "op_next_enumerator_pname");
     1423            printLocationAndOp(out, exec, location, it, "op_enumerator_structure_pname");
    14341424            out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data());
    1435             it += OPCODE_LENGTH(op_next_enumerator_pname) - 1;
     1425            it += OPCODE_LENGTH(op_enumerator_structure_pname) - 1;
     1426            break;
     1427        }
     1428        case op_enumerator_generic_pname: {
     1429            int dst = it[1].u.operand;
     1430            int enumerator = it[2].u.operand;
     1431            int index = it[3].u.operand;
     1432            printLocationAndOp(out, exec, location, it, "op_enumerator_generic_pname");
     1433            out.printf("%s, %s, %s", registerName(dst).data(), registerName(enumerator).data(), registerName(index).data());
     1434            it += OPCODE_LENGTH(op_enumerator_generic_pname) - 1;
    14361435            break;
    14371436        }
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r181611 r181891  
    27022702}
    27032703
    2704 RegisterID* BytecodeGenerator::emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length)
    2705 {
    2706     emitOpcode(op_get_structure_property_enumerator);
     2704RegisterID* BytecodeGenerator::emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base)
     2705{
     2706    emitOpcode(op_get_property_enumerator);
    27072707    instructions().append(dst->index());
    27082708    instructions().append(base->index());
    2709     instructions().append(length->index());
    2710     return dst;
    2711 }
    2712 
    2713 RegisterID* BytecodeGenerator::emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator)
    2714 {
    2715     emitOpcode(op_get_generic_property_enumerator);
    2716     instructions().append(dst->index());
    2717     instructions().append(base->index());
    2718     instructions().append(length->index());
    2719     instructions().append(structureEnumerator->index());
    2720     return dst;
    2721 }
    2722 
    2723 RegisterID* BytecodeGenerator::emitNextEnumeratorPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index)
    2724 {
    2725     emitOpcode(op_next_enumerator_pname);
     2709    return dst;
     2710}
     2711
     2712RegisterID* BytecodeGenerator::emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index)
     2713{
     2714    emitOpcode(op_enumerator_structure_pname);
     2715    instructions().append(dst->index());
     2716    instructions().append(enumerator->index());
     2717    instructions().append(index->index());
     2718    return dst;
     2719}
     2720
     2721RegisterID* BytecodeGenerator::emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index)
     2722{
     2723    emitOpcode(op_enumerator_generic_pname);
    27262724    instructions().append(dst->index());
    27272725    instructions().append(enumerator->index());
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r181611 r181891  
    532532        RegisterID* emitHasStructureProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName, RegisterID* enumerator);
    533533        RegisterID* emitHasGenericProperty(RegisterID* dst, RegisterID* base, RegisterID* propertyName);
     534        RegisterID* emitGetPropertyEnumerator(RegisterID* dst, RegisterID* base);
    534535        RegisterID* emitGetEnumerableLength(RegisterID* dst, RegisterID* base);
    535536        RegisterID* emitGetStructurePropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length);
    536537        RegisterID* emitGetGenericPropertyEnumerator(RegisterID* dst, RegisterID* base, RegisterID* length, RegisterID* structureEnumerator);
    537         RegisterID* emitNextEnumeratorPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
     538        RegisterID* emitEnumeratorStructurePropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
     539        RegisterID* emitEnumeratorGenericPropertyName(RegisterID* dst, RegisterID* enumerator, RegisterID* index);
    538540        RegisterID* emitToIndexString(RegisterID* dst, RegisterID* index);
    539541
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r181810 r181891  
    21842184    RefPtr<RegisterID> base = generator.newTemporary();
    21852185    RefPtr<RegisterID> length;
    2186     RefPtr<RegisterID> structureEnumerator;
     2186    RefPtr<RegisterID> enumerator;
    21872187    generator.emitNode(base.get(), m_expr);
    21882188    RefPtr<RegisterID> local = this->tryGetBoundLocal(generator);
     2189    RefPtr<RegisterID> enumeratorIndex;
    21892190
    21902191    int profilerStartOffset = m_statement->startOffset();
    21912192    int profilerEndOffset = m_statement->endOffset() + (m_statement->isBlock() ? 1 : 0);
     2193
     2194    enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get());
     2195
    21922196    // Indexed property loop.
    21932197    {
     
    21962200        RefPtr<Label> loopEnd = generator.newLabel();
    21972201
    2198         length = generator.emitGetEnumerableLength(generator.newTemporary(), base.get());
     2202        length = generator.emitGetEnumerableLength(generator.newTemporary(), enumerator.get());
    21992203        RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
    22002204        RefPtr<RegisterID> propertyName = generator.newTemporary();
     
    22342238        RefPtr<Label> loopEnd = generator.newLabel();
    22352239
    2236         structureEnumerator = generator.emitGetStructurePropertyEnumerator(generator.newTemporary(), base.get(), length.get());
    2237         RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
     2240        enumeratorIndex = generator.emitLoad(generator.newTemporary(), jsNumber(0));
    22382241        RefPtr<RegisterID> propertyName = generator.newTemporary();
    2239         generator.emitNextEnumeratorPropertyName(propertyName.get(), structureEnumerator.get(), i.get());
     2242        generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
    22402243
    22412244        generator.emitLabel(loopStart.get());
     
    22442247        RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
    22452248        generator.emitJumpIfTrue(result.get(), loopEnd.get());
    2246         generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), structureEnumerator.get());
     2249        generator.emitHasStructureProperty(result.get(), base.get(), propertyName.get(), enumerator.get());
    22472250        generator.emitJumpIfFalse(result.get(), scope->continueTarget());
    22482251
     
    22512254        generator.emitProfileControlFlow(profilerStartOffset);
    22522255
    2253         generator.pushStructureForInScope(local.get(), i.get(), propertyName.get(), structureEnumerator.get());
     2256        generator.pushStructureForInScope(local.get(), enumeratorIndex.get(), propertyName.get(), enumerator.get());
    22542257        generator.emitNode(dst, m_statement);
    22552258        generator.popStructureForInScope(local.get());
     
    22582261
    22592262        generator.emitLabel(scope->continueTarget());
    2260         generator.emitInc(i.get());
    2261         generator.emitNextEnumeratorPropertyName(propertyName.get(), structureEnumerator.get(), i.get());
     2263        generator.emitInc(enumeratorIndex.get());
     2264        generator.emitEnumeratorStructurePropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
    22622265        generator.emitJump(loopStart.get());
    22632266       
     
    22732276        RefPtr<Label> loopEnd = generator.newLabel();
    22742277
    2275         RefPtr<RegisterID> genericEnumerator = generator.emitGetGenericPropertyEnumerator(generator.newTemporary(), base.get(), length.get(), structureEnumerator.get());
    2276         RefPtr<RegisterID> i = generator.emitLoad(generator.newTemporary(), jsNumber(0));
    22772278        RefPtr<RegisterID> propertyName = generator.newTemporary();
    22782279
    2279         generator.emitNextEnumeratorPropertyName(propertyName.get(), genericEnumerator.get(), i.get());
     2280        generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
     2281
     2282        generator.emitLabel(loopStart.get());
     2283        generator.emitLoopHint();
     2284
    22802285        RefPtr<RegisterID> result = generator.emitUnaryOp(op_eq_null, generator.newTemporary(), propertyName.get());
    22812286        generator.emitJumpIfTrue(result.get(), loopEnd.get());
    22822287
    2283         generator.emitLabel(loopStart.get());
    2284         generator.emitLoopHint();
     2288        generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
     2289        generator.emitJumpIfFalse(result.get(), scope->continueTarget());
    22852290
    22862291        this->emitLoopHeader(generator, propertyName.get());
     
    22912296
    22922297        generator.emitLabel(scope->continueTarget());
    2293         generator.emitInc(i.get());
    2294         generator.emitNextEnumeratorPropertyName(propertyName.get(), genericEnumerator.get(), i.get());
    2295         generator.emitUnaryOp(op_eq_null, result.get(), propertyName.get());
    2296         generator.emitJumpIfTrue(result.get(), loopEnd.get());
    2297 
    2298         generator.emitHasGenericProperty(result.get(), base.get(), propertyName.get());
    2299         generator.emitJumpIfTrue(result.get(), loopStart.get());
    2300         generator.emitJump(scope->continueTarget());
    2301        
     2298        generator.emitInc(enumeratorIndex.get());
     2299        generator.emitEnumeratorGenericPropertyName(propertyName.get(), enumerator.get(), enumeratorIndex.get());
     2300        generator.emitJump(loopStart.get());
     2301
    23022302        generator.emitLabel(scope->breakTarget());
    23032303        generator.emitJump(end.get());
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r181650 r181891  
    19671967        break;
    19681968    }
    1969     case GetStructurePropertyEnumerator: {
     1969    case GetPropertyEnumerator: {
    19701970        forNode(node).setType(SpecCell);
    19711971        break;
    19721972    }
    1973     case GetGenericPropertyEnumerator: {
    1974         forNode(node).setType(SpecCell);
    1975         break;
    1976     }
    1977     case GetEnumeratorPname: {
     1973    case GetEnumeratorStructurePname: {
     1974        forNode(node).setType(SpecString | SpecOther);
     1975        break;
     1976    }
     1977    case GetEnumeratorGenericPname: {
    19781978        forNode(node).setType(SpecString | SpecOther);
    19791979        break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r181817 r181891  
    37713771        }
    37723772
    3773         case op_get_structure_property_enumerator: {
    3774             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetStructurePropertyEnumerator,
     3773        case op_get_property_enumerator: {
     3774            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetPropertyEnumerator,
     3775                get(VirtualRegister(currentInstruction[2].u.operand))));
     3776            NEXT_OPCODE(op_get_property_enumerator);
     3777        }
     3778
     3779        case op_enumerator_structure_pname: {
     3780            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorStructurePname,
    37753781                get(VirtualRegister(currentInstruction[2].u.operand)),
    37763782                get(VirtualRegister(currentInstruction[3].u.operand))));
    3777             NEXT_OPCODE(op_get_structure_property_enumerator);
    3778         }
    3779 
    3780         case op_get_generic_property_enumerator: {
    3781             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetGenericPropertyEnumerator,
    3782                 get(VirtualRegister(currentInstruction[2].u.operand)),
    3783                 get(VirtualRegister(currentInstruction[3].u.operand)),
    3784                 get(VirtualRegister(currentInstruction[4].u.operand))));
    3785             NEXT_OPCODE(op_get_generic_property_enumerator);
    3786         }
    3787 
    3788         case op_next_enumerator_pname: {
    3789             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorPname,
     3783            NEXT_OPCODE(op_enumerator_structure_pname);
     3784        }
     3785
     3786        case op_enumerator_generic_pname: {
     3787            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorGenericPname,
    37903788                get(VirtualRegister(currentInstruction[2].u.operand)),
    37913789                get(VirtualRegister(currentInstruction[3].u.operand))));
    3792             NEXT_OPCODE(op_next_enumerator_pname);
    3793         }
    3794 
     3790            NEXT_OPCODE(op_enumerator_generic_pname);
     3791        }
     3792           
    37953793        case op_to_index_string: {
    37963794            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ToIndexString,
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r181466 r181891  
    203203    case op_has_indexed_property:
    204204    case op_get_direct_pname:
    205     case op_get_structure_property_enumerator:
    206     case op_get_generic_property_enumerator:
    207     case op_next_enumerator_pname:
     205    case op_get_property_enumerator:
     206    case op_enumerator_structure_pname:
     207    case op_enumerator_generic_pname:
    208208    case op_to_index_string:
    209209    case op_new_func:
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r181650 r181891  
    163163    case HasStructureProperty:
    164164    case GetEnumerableLength:
    165     case GetStructurePropertyEnumerator:
    166     case GetGenericPropertyEnumerator: {
     165    case GetPropertyEnumerator: {
    167166        read(Heap);
    168167        write(SideState);
     
    179178
    180179    case ToIndexString:
    181     case GetEnumeratorPname: {
     180    case GetEnumeratorStructurePname:
     181    case GetEnumeratorGenericPname: {
    182182        def(PureValue(node));
    183183        return;
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r181650 r181891  
    232232    case NewTypedArray:
    233233    case ThrowReferenceError:
    234     case GetStructurePropertyEnumerator:
    235     case GetGenericPropertyEnumerator:
    236     case GetEnumeratorPname:
     234    case GetPropertyEnumerator:
     235    case GetEnumeratorStructurePname:
     236    case GetEnumeratorGenericPname:
    237237    case ToIndexString:
    238238    case MaterializeNewObject:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r181817 r181891  
    10921092        }
    10931093        case HasGenericProperty: {
    1094             fixEdge<StringUse>(node->child2());
     1094            fixEdge<CellUse>(node->child2());
    10951095            break;
    10961096        }
     
    11241124            break;
    11251125        }
    1126         case GetStructurePropertyEnumerator: {
     1126        case GetPropertyEnumerator: {
    11271127            fixEdge<CellUse>(node->child1());
     1128            break;
     1129        }
     1130        case GetEnumeratorStructurePname: {
     1131            fixEdge<KnownCellUse>(node->child1());
    11281132            fixEdge<KnownInt32Use>(node->child2());
    11291133            break;
    11301134        }
    1131         case GetGenericPropertyEnumerator: {
    1132             fixEdge<CellUse>(node->child1());
    1133             fixEdge<KnownInt32Use>(node->child2());
    1134             fixEdge<KnownCellUse>(node->child3());
    1135             break;
    1136         }
    1137         case GetEnumeratorPname: {
     1135        case GetEnumeratorGenericPname: {
    11381136            fixEdge<KnownCellUse>(node->child1());
    11391137            fixEdge<KnownInt32Use>(node->child2());
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r181650 r181891  
    323323    macro(HasGenericProperty, NodeResultBoolean) \
    324324    macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
    325     macro(GetStructurePropertyEnumerator, NodeMustGenerate | NodeResultJS) \
    326     macro(GetGenericPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
    327     macro(GetEnumeratorPname, NodeMustGenerate | NodeResultJS) \
     325    macro(GetPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
     326    macro(GetEnumeratorStructurePname, NodeMustGenerate | NodeResultJS) \
     327    macro(GetEnumeratorGenericPname, NodeMustGenerate | NodeResultJS) \
    328328    macro(ToIndexString, NodeResultJS)
    329329
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r181650 r181891  
    584584            break;
    585585        }
    586         case GetStructurePropertyEnumerator:
    587         case GetGenericPropertyEnumerator: {
     586        case GetPropertyEnumerator: {
    588587            changed |= setPrediction(SpecCell);
    589588            break;
    590589        }
    591         case GetEnumeratorPname: {
     590        case GetEnumeratorStructurePname: {
     591            changed |= setPrediction(SpecCell | SpecOther);
     592            break;
     593        }
     594        case GetEnumeratorGenericPname: {
    592595            changed |= setPrediction(SpecCell | SpecOther);
    593596            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r181650 r181891  
    273273    case HasIndexedProperty:
    274274    case GetDirectPname:
    275     case GetStructurePropertyEnumerator:
    276     case GetGenericPropertyEnumerator:
    277     case GetEnumeratorPname:
     275    case GetPropertyEnumerator:
     276    case GetEnumeratorStructurePname:
     277    case GetEnumeratorGenericPname:
    278278    case ToIndexString:
    279279    case PhantomNewObject:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r181650 r181891  
    47164716
    47174717    case GetEnumerableLength: {
    4718         SpeculateCellOperand base(this, node->child1());
     4718        SpeculateCellOperand enumerator(this, node->child1());
    47194719        GPRFlushedCallResult result(this);
    47204720        GPRReg resultGPR = result.gpr();
    47214721
    4722         flushRegisters();
    4723         callOperation(operationGetEnumerableLength, resultGPR, base.gpr());
     4722        m_jit.load32(MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::indexedLengthOffset()), resultGPR);
    47244723        int32Result(resultGPR, node);
    47254724        break;
     
    49134912        break;
    49144913    }
    4915     case GetStructurePropertyEnumerator: {
     4914    case GetPropertyEnumerator: {
    49164915        SpeculateCellOperand base(this, node->child1());
    4917         SpeculateInt32Operand length(this, node->child2());
    49184916        GPRFlushedCallResult result(this);
    49194917        GPRReg resultGPR = result.gpr();
    49204918
    49214919        flushRegisters();
    4922         callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr());
     4920        callOperation(operationGetPropertyEnumerator, resultGPR, base.gpr());
    49234921        cellResult(resultGPR, node);
    49244922        break;
    49254923    }
    4926     case GetGenericPropertyEnumerator: {
    4927         SpeculateCellOperand base(this, node->child1());
    4928         SpeculateInt32Operand length(this, node->child2());
    4929         SpeculateCellOperand enumerator(this, node->child3());
    4930         GPRFlushedCallResult result(this);
    4931         GPRReg resultGPR = result.gpr();
    4932 
    4933         flushRegisters();
    4934         callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr());
    4935         cellResult(resultGPR, node);
    4936         break;
    4937     }
    4938     case GetEnumeratorPname: {
     4924    case GetEnumeratorStructurePname:
     4925    case GetEnumeratorGenericPname: {
    49394926        SpeculateCellOperand enumerator(this, node->child1());
    49404927        SpeculateInt32Operand index(this, node->child2());
     
    49494936        GPRReg resultPayloadGPR = resultPayload.gpr();
    49504937
    4951         MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below,
    4952             indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
     4938        MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, indexGPR,
     4939            MacroAssembler::Address(enumeratorGPR, (op == GetEnumeratorStructurePname)
     4940                ? JSPropertyNameEnumerator::endStructurePropertyIndexOffset()
     4941                : JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
    49534942
    49544943        m_jit.move(MacroAssembler::TrustedImm32(JSValue::NullTag), resultTagGPR);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r181650 r181891  
    47734773
    47744774    case GetEnumerableLength: {
    4775         SpeculateCellOperand base(this, node->child1());
     4775        SpeculateCellOperand enumerator(this, node->child1());
    47764776        GPRFlushedCallResult result(this);
    47774777        GPRReg resultGPR = result.gpr();
    47784778
    4779         flushRegisters();
    4780         callOperation(operationGetEnumerableLength, resultGPR, base.gpr());
     4779        m_jit.load32(MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::indexedLengthOffset()), resultGPR);
    47814780        int32Result(resultGPR, node);
    47824781        break;
     
    49494948        break;
    49504949    }
    4951     case GetStructurePropertyEnumerator: {
     4950    case GetPropertyEnumerator: {
    49524951        SpeculateCellOperand base(this, node->child1());
    4953         SpeculateInt32Operand length(this, node->child2());
    49544952        GPRFlushedCallResult result(this);
    49554953        GPRReg resultGPR = result.gpr();
    49564954
    49574955        flushRegisters();
    4958         callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr());
     4956        callOperation(operationGetPropertyEnumerator, resultGPR, base.gpr());
    49594957        cellResult(resultGPR, node);
    49604958        break;
    49614959    }
    4962     case GetGenericPropertyEnumerator: {
    4963         SpeculateCellOperand base(this, node->child1());
    4964         SpeculateInt32Operand length(this, node->child2());
    4965         SpeculateCellOperand enumerator(this, node->child3());
    4966         GPRFlushedCallResult result(this);
    4967         GPRReg resultGPR = result.gpr();
    4968 
    4969         flushRegisters();
    4970         callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr());
    4971         cellResult(resultGPR, node);
    4972         break;
    4973     }
    4974     case GetEnumeratorPname: {
     4960    case GetEnumeratorStructurePname:
     4961    case GetEnumeratorGenericPname: {
    49754962        SpeculateCellOperand enumerator(this, node->child1());
    49764963        SpeculateStrictInt32Operand index(this, node->child2());
     
    49834970        GPRReg resultGPR = result.gpr();
    49844971
    4985         MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below,
    4986             indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
     4972        MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, indexGPR,
     4973            MacroAssembler::Address(enumeratorGPR, (op == GetEnumeratorStructurePname)
     4974                ? JSPropertyNameEnumerator::endStructurePropertyIndexOffset()
     4975                : JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
    49874976
    49884977        m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsNull())), resultGPR);
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r173837 r181891  
    6262    macro(JSObject_butterfly, JSObject::butterflyOffset()) \
    6363    macro(JSPropertyNameEnumerator_cachedInlineCapacity, JSPropertyNameEnumerator::cachedInlineCapacityOffset()) \
    64     macro(JSPropertyNameEnumerator_cachedPropertyNamesLength, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()) \
    6564    macro(JSPropertyNameEnumerator_cachedPropertyNamesVector, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()) \
    6665    macro(JSPropertyNameEnumerator_cachedStructureID, JSPropertyNameEnumerator::cachedStructureIDOffset()) \
     66    macro(JSPropertyNameEnumerator_endGenericPropertyIndex, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()) \
     67    macro(JSPropertyNameEnumerator_endStructurePropertyIndex, JSPropertyNameEnumerator::endStructurePropertyIndexOffset()) \
     68    macro(JSPropertyNameEnumerator_indexLength, JSPropertyNameEnumerator::indexedLengthOffset()) \
    6769    macro(JSScope_next, JSScope::offsetOfNext()) \
    6870    macro(JSString_flags, JSString::offsetOfFlags()) \
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r181650 r181891  
    172172    case GetDirectPname:
    173173    case GetEnumerableLength:
    174     case GetStructurePropertyEnumerator:
    175     case GetGenericPropertyEnumerator:
    176     case GetEnumeratorPname:
     174    case GetPropertyEnumerator:
     175    case GetEnumeratorStructurePname:
     176    case GetEnumeratorGenericPname:
    177177    case ToIndexString:
    178178    case BottomValue:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r181650 r181891  
    804804            compileGetEnumerableLength();
    805805            break;
    806         case GetStructurePropertyEnumerator:
    807             compileGetStructurePropertyEnumerator();
    808             break;
    809         case GetGenericPropertyEnumerator:
    810             compileGetGenericPropertyEnumerator();
    811             break;
    812         case GetEnumeratorPname:
    813             compileGetEnumeratorPname();
     806        case GetPropertyEnumerator:
     807            compileGetPropertyEnumerator();
     808            break;
     809        case GetEnumeratorStructurePname:
     810            compileGetEnumeratorStructurePname();
     811            break;
     812        case GetEnumeratorGenericPname:
     813            compileGetEnumeratorGenericPname();
    814814            break;
    815815        case ToIndexString:
     
    45274527    void compileGetEnumerableLength()
    45284528    {
     4529        LValue enumerator = lowCell(m_node->child1());
     4530        setInt32(m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_indexLength));
     4531    }
     4532
     4533    void compileGetPropertyEnumerator()
     4534    {
    45294535        LValue base = lowCell(m_node->child1());
    4530         setInt32(vmCall(m_out.operation(operationGetEnumerableLength), m_callFrame, base));
    4531     }
    4532 
    4533     void compileGetStructurePropertyEnumerator()
    4534     {
    4535         LValue base = lowCell(m_node->child1());
    4536         LValue length = lowInt32(m_node->child2());
    4537         setJSValue(vmCall(m_out.operation(operationGetStructurePropertyEnumerator), m_callFrame, base, length));
    4538     }
    4539 
    4540     void compileGetGenericPropertyEnumerator()
    4541     {
    4542         LValue base = lowCell(m_node->child1());
    4543         LValue length = lowInt32(m_node->child2());
    4544         LValue enumerator = lowCell(m_node->child3());
    4545         setJSValue(vmCall(m_out.operation(operationGetGenericPropertyEnumerator), m_callFrame, base, length, enumerator));
    4546     }
    4547 
    4548     void compileGetEnumeratorPname()
     4536        setJSValue(vmCall(m_out.operation(operationGetPropertyEnumerator), m_callFrame, base));
     4537    }
     4538
     4539    void compileGetEnumeratorStructurePname()
    45494540    {
    45504541        LValue enumerator = lowCell(m_node->child1());
    45514542        LValue index = lowInt32(m_node->child2());
    45524543
    4553         LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorPname in bounds"));
    4554         LBasicBlock outOfBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorPname out of bounds"));
    4555         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetEnumeratorPname continuation"));
    4556 
    4557         m_out.branch(m_out.below(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesLength)),
     4544        LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorStructurePname in bounds"));
     4545        LBasicBlock outOfBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorStructurePname out of bounds"));
     4546        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetEnumeratorStructurePname continuation"));
     4547
     4548        m_out.branch(m_out.below(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_endStructurePropertyIndex)),
    45584549            usually(inBounds), rarely(outOfBounds));
    45594550
     
    45734564    }
    45744565
     4566    void compileGetEnumeratorGenericPname()
     4567    {
     4568        LValue enumerator = lowCell(m_node->child1());
     4569        LValue index = lowInt32(m_node->child2());
     4570
     4571        LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorGenericPname in bounds"));
     4572        LBasicBlock outOfBounds = FTL_NEW_BLOCK(m_out, ("GetEnumeratorGenericPname out of bounds"));
     4573        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetEnumeratorGenericPname continuation"));
     4574
     4575        m_out.branch(m_out.below(index, m_out.load32(enumerator, m_heaps.JSPropertyNameEnumerator_endGenericPropertyIndex)),
     4576            usually(inBounds), rarely(outOfBounds));
     4577
     4578        LBasicBlock lastNext = m_out.appendTo(inBounds, outOfBounds);
     4579        LValue storage = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
     4580        ValueFromBlock inBoundsResult = m_out.anchor(
     4581            m_out.load64(m_out.baseIndex(m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector,
     4582                storage, m_out.signExt(index, m_out.int64), ScaleEight)));
     4583        m_out.jump(continuation);
     4584
     4585        m_out.appendTo(outOfBounds, continuation);
     4586        ValueFromBlock outOfBoundsResult = m_out.anchor(m_out.constInt64(ValueNull));
     4587        m_out.jump(continuation);
     4588       
     4589        m_out.appendTo(continuation, lastNext);
     4590        setJSValue(m_out.phi(m_out.int64, inBoundsResult, outOfBoundsResult));
     4591    }
     4592   
    45754593    void compileToIndexString()
    45764594    {
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r181887 r181891  
    307307        DEFINE_OP(op_has_indexed_property)
    308308        DEFINE_OP(op_get_direct_pname)
    309         DEFINE_OP(op_get_structure_property_enumerator)
    310         DEFINE_OP(op_get_generic_property_enumerator)
    311         DEFINE_OP(op_next_enumerator_pname)
     309        DEFINE_OP(op_get_property_enumerator)
     310        DEFINE_OP(op_enumerator_structure_pname)
     311        DEFINE_OP(op_enumerator_generic_pname)
    312312        DEFINE_OP(op_to_index_string)
    313313        default:
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r181466 r181891  
    558558        void emit_op_has_indexed_property(Instruction*);
    559559        void emit_op_get_direct_pname(Instruction*);
    560         void emit_op_get_structure_property_enumerator(Instruction*);
    561         void emit_op_get_generic_property_enumerator(Instruction*);
    562         void emit_op_next_enumerator_pname(Instruction*);
     560        void emit_op_get_property_enumerator(Instruction*);
     561        void emit_op_enumerator_structure_pname(Instruction*);
     562        void emit_op_enumerator_generic_pname(Instruction*);
    563563        void emit_op_to_index_string(Instruction*);
    564564
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r181466 r181891  
    12851285}
    12861286
    1287 void JIT::emit_op_next_enumerator_pname(Instruction* currentInstruction)
     1287void JIT::emit_op_enumerator_structure_pname(Instruction* currentInstruction)
    12881288{
    12891289    int dst = currentInstruction[1].u.operand;
     
    12931293    emitGetVirtualRegister(index, regT0);
    12941294    emitGetVirtualRegister(enumerator, regT1);
    1295     Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
     1295    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endStructurePropertyIndexOffset()));
    12961296
    12971297    move(TrustedImm64(JSValue::encode(jsNull())), regT0);
     
    13041304    load64(BaseIndex(regT1, regT0, TimesEight), regT0);
    13051305
     1306    done.link(this);
     1307    emitPutVirtualRegister(dst);
     1308}
     1309
     1310void JIT::emit_op_enumerator_generic_pname(Instruction* currentInstruction)
     1311{
     1312    int dst = currentInstruction[1].u.operand;
     1313    int enumerator = currentInstruction[2].u.operand;
     1314    int index = currentInstruction[3].u.operand;
     1315
     1316    emitGetVirtualRegister(index, regT0);
     1317    emitGetVirtualRegister(enumerator, regT1);
     1318    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
     1319
     1320    move(TrustedImm64(JSValue::encode(jsNull())), regT0);
     1321
     1322    Jump done = jump();
     1323    inBounds.link(this);
     1324
     1325    loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1);
     1326    signExtend32ToPtr(regT0, regT0);
     1327    load64(BaseIndex(regT1, regT0, TimesEight), regT0);
     1328   
    13061329    done.link(this);
    13071330    emitPutVirtualRegister(dst);
     
    13931416}
    13941417
    1395 void JIT::emit_op_get_structure_property_enumerator(Instruction* currentInstruction)
    1396 {
    1397     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_structure_property_enumerator);
    1398     slowPathCall.call();
    1399 }
    1400 
    1401 void JIT::emit_op_get_generic_property_enumerator(Instruction* currentInstruction)
    1402 {
    1403     JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_generic_property_enumerator);
     1418void JIT::emit_op_get_property_enumerator(Instruction* currentInstruction)
     1419{
     1420    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_get_property_enumerator);
    14041421    slowPathCall.call();
    14051422}
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r181466 r181891  
    12601260}
    12611261
    1262 void JIT::emit_op_next_enumerator_pname(Instruction* currentInstruction)
     1262void JIT::emit_op_enumerator_structure_pname(Instruction* currentInstruction)
    12631263{
    12641264    int dst = currentInstruction[1].u.operand;
     
    12681268    emitLoadPayload(index, regT0);
    12691269    emitLoadPayload(enumerator, regT1);
    1270     Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
     1270    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endStructurePropertyIndexOffset()));
    12711271
    12721272    move(TrustedImm32(JSValue::NullTag), regT2);
     
    12801280    move(TrustedImm32(JSValue::CellTag), regT2);
    12811281
     1282    done.link(this);
     1283    emitStore(dst, regT2, regT0);
     1284}
     1285
     1286void JIT::emit_op_enumerator_generic_pname(Instruction* currentInstruction)
     1287{
     1288    int dst = currentInstruction[1].u.operand;
     1289    int enumerator = currentInstruction[2].u.operand;
     1290    int index = currentInstruction[3].u.operand;
     1291
     1292    emitLoadPayload(index, regT0);
     1293    emitLoadPayload(enumerator, regT1);
     1294    Jump inBounds = branch32(Below, regT0, Address(regT1, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
     1295
     1296    move(TrustedImm32(JSValue::NullTag), regT2);
     1297    move(TrustedImm32(0), regT0);
     1298
     1299    Jump done = jump();
     1300    inBounds.link(this);
     1301
     1302    loadPtr(Address(regT1, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), regT1);
     1303    loadPtr(BaseIndex(regT1, regT0, timesPtr()), regT0);
     1304    move(TrustedImm32(JSValue::CellTag), regT2);
     1305   
    12821306    done.link(this);
    12831307    emitStore(dst, regT2, regT0);
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r181889 r181891  
    18481848}
    18491849
    1850 int32_t JIT_OPERATION operationGetEnumerableLength(ExecState* exec, JSCell* baseCell)
    1851 {
    1852     VM& vm = exec->vm();
    1853     NativeCallFrameTracer tracer(&vm, exec);
    1854     JSObject* base = baseCell->toObject(exec, exec->lexicalGlobalObject());
    1855     return base->methodTable(vm)->getEnumerableLength(exec, base);
    1856 }
    1857 
    18581850EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState* exec, EncodedJSValue encodedBaseValue, JSCell* propertyName)
    18591851{
     
    18761868}
    18771869   
    1878 JSCell* JIT_OPERATION operationGetStructurePropertyEnumerator(ExecState* exec, JSCell* cell, int32_t length)
    1879 {
    1880     VM& vm = exec->vm();
    1881     NativeCallFrameTracer tracer(&vm, exec);
    1882        
     1870JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState* exec, JSCell* cell)
     1871{
     1872    VM& vm = exec->vm();
     1873    NativeCallFrameTracer tracer(&vm, exec);
     1874
    18831875    JSObject* base = cell->toObject(exec, exec->lexicalGlobalObject());
    1884     ASSERT(length >= 0);
    1885 
    1886     return structurePropertyNameEnumerator(exec, base, static_cast<uint32_t>(length));
    1887 }
    1888 
    1889 JSCell* JIT_OPERATION operationGetGenericPropertyEnumerator(ExecState* exec, JSCell* baseCell, int32_t length, JSCell* structureEnumeratorCell)
    1890 {
    1891     VM& vm = exec->vm();
    1892     NativeCallFrameTracer tracer(&vm, exec);
    1893    
    1894     JSObject* base = baseCell->toObject(exec, exec->lexicalGlobalObject());
    1895     ASSERT(length >= 0);
    1896 
    1897     return genericPropertyNameEnumerator(exec, base, length, jsCast<JSPropertyNameEnumerator*>(structureEnumeratorCell));
     1876
     1877    return propertyNameEnumerator(exec, base);
    18981878}
    18991879
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r180514 r181891  
    328328void JIT_OPERATION operationExceptionFuzz();
    329329
    330 int32_t JIT_OPERATION operationGetEnumerableLength(ExecState*, JSCell*);
    331330EncodedJSValue JIT_OPERATION operationHasGenericProperty(ExecState*, EncodedJSValue, JSCell*);
    332331EncodedJSValue JIT_OPERATION operationHasIndexedProperty(ExecState*, JSCell*, int32_t);
    333 JSCell* JIT_OPERATION operationGetStructurePropertyEnumerator(ExecState*, JSCell*, int32_t);
    334 JSCell* JIT_OPERATION operationGetGenericPropertyEnumerator(ExecState*, JSCell*, int32_t, JSCell*);
     332JSCell* JIT_OPERATION operationGetPropertyEnumerator(ExecState*, JSCell*);
    335333EncodedJSValue JIT_OPERATION operationNextEnumeratorPname(ExecState*, JSCell*, int32_t);
    336334JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r180587 r181891  
    13351335    dispatch(7)
    13361336
    1337 _llint_op_get_structure_property_enumerator:
    1338     traceExecution()
    1339     callSlowPath(_slow_path_get_structure_property_enumerator)
    1340     dispatch(4)
    1341 
    1342 _llint_op_get_generic_property_enumerator:
    1343     traceExecution()
    1344     callSlowPath(_slow_path_get_generic_property_enumerator)
    1345     dispatch(5)
    1346 
    1347 _llint_op_next_enumerator_pname:
    1348     traceExecution()
    1349     callSlowPath(_slow_path_next_enumerator_pname)
     1337_llint_op_get_property_enumerator:
     1338    traceExecution()
     1339    callSlowPath(_slow_path_get_property_enumerator)
     1340    dispatch(3)
     1341
     1342_llint_op_enumerator_structure_pname:
     1343    traceExecution()
     1344    callSlowPath(_slow_path_next_structure_enumerator_pname)
     1345    dispatch(4)
     1346
     1347_llint_op_enumerator_generic_pname:
     1348    traceExecution()
     1349    callSlowPath(_slow_path_next_generic_enumerator_pname)
    13501350    dispatch(4)
    13511351
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r181814 r181891  
    521521{
    522522    BEGIN();
    523     JSValue baseValue = OP(2).jsValue();
    524     if (baseValue.isUndefinedOrNull())
     523    JSValue enumeratorValue = OP(2).jsValue();
     524    if (enumeratorValue.isUndefinedOrNull())
    525525        RETURN(jsNumber(0));
    526526
    527     JSObject* base = baseValue.toObject(exec);
    528     RETURN(jsNumber(base->methodTable(vm)->getEnumerableLength(exec, base)));
     527    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(enumeratorValue.asCell());
     528
     529    RETURN(jsNumber(enumerator->indexedLength()));
    529530}
    530531
     
    575576}
    576577
    577 SLOW_PATH_DECL(slow_path_get_structure_property_enumerator)
     578SLOW_PATH_DECL(slow_path_get_property_enumerator)
    578579{
    579580    BEGIN();
     
    581582    if (baseValue.isUndefinedOrNull())
    582583        RETURN(JSPropertyNameEnumerator::create(vm));
    583        
     584
    584585    JSObject* base = baseValue.toObject(exec);
    585     uint32_t length = OP(3).jsValue().asUInt32();
    586 
    587     RETURN(structurePropertyNameEnumerator(exec, base, length));
    588 }
    589 
    590 SLOW_PATH_DECL(slow_path_get_generic_property_enumerator)
    591 {
    592     BEGIN();
    593     JSValue baseValue = OP(2).jsValue();
    594     if (baseValue.isUndefinedOrNull())
    595         RETURN(JSPropertyNameEnumerator::create(vm));
    596    
    597     JSObject* base = baseValue.toObject(exec);
    598     uint32_t length = OP(3).jsValue().asUInt32();
    599     JSPropertyNameEnumerator* structureEnumerator = jsCast<JSPropertyNameEnumerator*>(OP(4).jsValue().asCell());
    600 
    601     RETURN(genericPropertyNameEnumerator(exec, base, length, structureEnumerator));
    602 }
    603 
    604 SLOW_PATH_DECL(slow_path_next_enumerator_pname)
     586
     587    RETURN(propertyNameEnumerator(exec, base));
     588}
     589
     590SLOW_PATH_DECL(slow_path_next_structure_enumerator_pname)
    605591{
    606592    BEGIN();
    607593    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell());
    608594    uint32_t index = OP(3).jsValue().asUInt32();
    609     JSString* propertyName = enumerator->propertyNameAtIndex(index);
     595
     596    JSString* propertyName = nullptr;
     597    if (index < enumerator->endStructurePropertyIndex())
     598        propertyName = enumerator->propertyNameAtIndex(index);
     599    RETURN(propertyName ? propertyName : jsNull());
     600}
     601
     602SLOW_PATH_DECL(slow_path_next_generic_enumerator_pname)
     603{
     604    BEGIN();
     605    JSPropertyNameEnumerator* enumerator = jsCast<JSPropertyNameEnumerator*>(OP(2).jsValue().asCell());
     606    uint32_t index = OP(3).jsValue().asUInt32();
     607
     608    JSString* propertyName = nullptr;
     609    if (enumerator->endStructurePropertyIndex() <= index && index < enumerator->endGenericPropertyIndex())
     610        propertyName = enumerator->propertyNameAtIndex(index);
    610611    RETURN(propertyName ? propertyName : jsNull());
    611612}
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r181889 r181891  
    227227SLOW_PATH_HIDDEN_DECL(slow_path_has_indexed_property);
    228228SLOW_PATH_HIDDEN_DECL(slow_path_get_direct_pname);
    229 SLOW_PATH_HIDDEN_DECL(slow_path_get_structure_property_enumerator);
    230 SLOW_PATH_HIDDEN_DECL(slow_path_get_generic_property_enumerator);
    231 SLOW_PATH_HIDDEN_DECL(slow_path_next_enumerator_pname);
     229SLOW_PATH_HIDDEN_DECL(slow_path_get_property_enumerator);
     230SLOW_PATH_HIDDEN_DECL(slow_path_next_structure_enumerator_pname);
     231SLOW_PATH_HIDDEN_DECL(slow_path_next_generic_enumerator_pname);
    232232SLOW_PATH_HIDDEN_DECL(slow_path_to_index_string);
    233233SLOW_PATH_HIDDEN_DECL(slow_path_profile_type_clear_log);
  • trunk/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.cpp

    r172176 r181891  
    3838    if (!vm.emptyPropertyNameEnumerator.get()) {
    3939        PropertyNameArray propertyNames(&vm);
    40         vm.emptyPropertyNameEnumerator = Strong<JSCell>(vm, create(vm, 0, propertyNames));
     40        vm.emptyPropertyNameEnumerator = Strong<JSCell>(vm, create(vm, 0, 0, 0, propertyNames));
    4141    }
    4242    return jsCast<JSPropertyNameEnumerator*>(vm.emptyPropertyNameEnumerator.get());
    4343}
    4444
    45 JSPropertyNameEnumerator* JSPropertyNameEnumerator::create(VM& vm, Structure* structure, PropertyNameArray& propertyNames)
     45JSPropertyNameEnumerator* JSPropertyNameEnumerator::create(VM& vm, Structure* structure, uint32_t indexedLength, uint32_t numberStructureProperties, PropertyNameArray& propertyNames)
    4646{
    4747    StructureID structureID = structure ? structure->id() : 0;
     
    4949    JSPropertyNameEnumerator* enumerator = new (NotNull,
    5050        allocateCell<JSPropertyNameEnumerator>(vm.heap)) JSPropertyNameEnumerator(vm, structureID, inlineCapacity, propertyNames.identifierSet());
    51     enumerator->finishCreation(vm, propertyNames.data());
     51    enumerator->finishCreation(vm, indexedLength, numberStructureProperties, propertyNames.data());
    5252    return enumerator;
    5353}
     
    6161}
    6262
    63 void JSPropertyNameEnumerator::finishCreation(VM& vm, PassRefPtr<PropertyNameArrayData> idents)
     63void JSPropertyNameEnumerator::finishCreation(VM& vm, uint32_t indexedLength, uint32_t endStructurePropertyIndex, PassRefPtr<PropertyNameArrayData> idents)
    6464{
    6565    Base::finishCreation(vm);
     
    6767    RefPtr<PropertyNameArrayData> identifiers = idents;
    6868    PropertyNameArrayData::PropertyNameVector& vector = identifiers->propertyNameVector();
     69
     70    m_indexedLength = indexedLength;
     71    m_endStructurePropertyIndex = endStructurePropertyIndex;
     72    m_endGenericPropertyIndex = vector.size();
     73
    6974    m_propertyNames.resize(vector.size());
    7075    for (unsigned i = 0; i < vector.size(); ++i) {
  • trunk/Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h

    r178441 r181891  
    4141
    4242    static JSPropertyNameEnumerator* create(VM&);
    43     static JSPropertyNameEnumerator* create(VM&, Structure*, PropertyNameArray&);
     43    static JSPropertyNameEnumerator* create(VM&, Structure*, uint32_t, uint32_t, PropertyNameArray&);
    4444
    4545    static const bool needsDestruction = true;
     
    7676    }
    7777    StructureID cachedStructureID() const { return m_cachedStructureID; }
     78    uint32_t indexedLength() const { return m_indexedLength; }
     79    uint32_t endStructurePropertyIndex() const { return m_endStructurePropertyIndex; }
     80    uint32_t endGenericPropertyIndex() const { return m_endGenericPropertyIndex; }
    7881    uint32_t cachedInlineCapacity() const { return m_cachedInlineCapacity; }
    7982    static ptrdiff_t cachedStructureIDOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_cachedStructureID); }
     83    static ptrdiff_t indexedLengthOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_indexedLength); }
     84    static ptrdiff_t endStructurePropertyIndexOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_endStructurePropertyIndex); }
     85    static ptrdiff_t endGenericPropertyIndexOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_endGenericPropertyIndex); }
    8086    static ptrdiff_t cachedInlineCapacityOffset() { return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_cachedInlineCapacity); }
    81     static ptrdiff_t cachedPropertyNamesLengthOffset()
    82     {
    83         return OBJECT_OFFSETOF(JSPropertyNameEnumerator, m_propertyNames) + Vector<WriteBarrier<JSString>>::sizeMemoryOffset();
    84     }
    8587    static ptrdiff_t cachedPropertyNamesVectorOffset()
    8688    {
     
    9496
    9597    JSPropertyNameEnumerator(VM&, StructureID, uint32_t, RefCountedIdentifierSet*);
    96     void finishCreation(VM&, PassRefPtr<PropertyNameArrayData>);
     98    void finishCreation(VM&, uint32_t, uint32_t, PassRefPtr<PropertyNameArrayData>);
    9799
    98100    Vector<WriteBarrier<JSString>> m_propertyNames;
     
    100102    StructureID m_cachedStructureID;
    101103    WriteBarrier<StructureChain> m_prototypeChain;
     104    uint32_t m_indexedLength;
     105    uint32_t m_endStructurePropertyIndex;
     106    uint32_t m_endGenericPropertyIndex;
    102107    uint32_t m_cachedInlineCapacity;
    103108};
    104109
    105 inline JSPropertyNameEnumerator* structurePropertyNameEnumerator(ExecState* exec, JSObject* base, uint32_t length)
     110inline JSPropertyNameEnumerator* propertyNameEnumerator(ExecState* exec, JSObject* base)
    106111{
    107112    VM& vm = exec->vm();
     113
     114    uint32_t indexedLength = base->methodTable(vm)->getEnumerableLength(exec, base);
     115
     116    JSPropertyNameEnumerator* enumerator = nullptr;
     117
    108118    Structure* structure = base->structure(vm);
    109     if (JSPropertyNameEnumerator* enumerator = structure->cachedStructurePropertyNameEnumerator())
     119    if (!indexedLength
     120        && (enumerator = structure->cachedPropertyNameEnumerator())
     121        && enumerator->cachedPrototypeChain() == structure->prototypeChain(exec))
    110122        return enumerator;
    111123
    112     if (!structure->canAccessPropertiesQuickly() || length != base->getArrayLength())
    113         return JSPropertyNameEnumerator::create(vm);
     124    uint32_t numberStructureProperties = 0;
    114125
    115126    PropertyNameArray propertyNames(exec);
    116     base->methodTable(vm)->getStructurePropertyNames(base, exec, propertyNames, ExcludeDontEnumProperties);
    117127
    118     JSPropertyNameEnumerator* enumerator = JSPropertyNameEnumerator::create(vm, structure, propertyNames);
    119     if (structure->canCacheStructurePropertyNameEnumerator())
    120         structure->setCachedStructurePropertyNameEnumerator(vm, enumerator);
    121     return enumerator;
    122 }
     128    if (structure->canAccessPropertiesQuickly() && indexedLength == base->getArrayLength()) {
     129        base->methodTable(vm)->getStructurePropertyNames(base, exec, propertyNames, ExcludeDontEnumProperties);
    123130
    124 inline JSPropertyNameEnumerator* genericPropertyNameEnumerator(ExecState* exec, JSObject* base, uint32_t length, JSPropertyNameEnumerator* structureEnumerator)
    125 {
    126     VM& vm = exec->vm();
    127     Structure* structure = base->structure(vm);
    128     if (JSPropertyNameEnumerator* enumerator = structure->cachedGenericPropertyNameEnumerator()) {
    129         if (!length && enumerator->cachedPrototypeChain() == structure->prototypeChain(exec))
    130             return enumerator;
    131     }
     131        numberStructureProperties = propertyNames.size();
    132132
    133     PropertyNameArray propertyNames(exec);
    134     propertyNames.setPreviouslyEnumeratedLength(length);
    135     propertyNames.setPreviouslyEnumeratedProperties(structureEnumerator);
     133        base->methodTable(vm)->getGenericPropertyNames(base, exec, propertyNames, ExcludeDontEnumProperties);
     134    } else
     135        base->methodTable(vm)->getPropertyNames(base, exec, propertyNames, ExcludeDontEnumProperties);
    136136
    137     // If we still have the same Structure that we started with, our Structure allows us to access its properties
    138     // quickly (i.e. the Structure property loop was able to do things), and we iterated the full length of the
    139     // object (i.e. there are no more own indexed properties that need to be enumerated), then the generic property
    140     // iteration can skip any properties it would get from the JSObject base class. This turns out to be important
    141     // for hot loops because most of our time is then dominated by trying to add the own Structure properties to
    142     // the new generic PropertyNameArray and failing because we've already visited them.
    143     Structure* cachedStructure = structureEnumerator->cachedStructure(vm);
    144     if (structure == cachedStructure && structure->canAccessPropertiesQuickly() && static_cast<uint32_t>(length) == base->getArrayLength())
    145         base->methodTable(vm)->getGenericPropertyNames(base, exec, propertyNames, ExcludeDontEnumProperties);
    146     else
    147         base->methodTable(vm)->getPropertyNames(base, exec, propertyNames, ExcludeDontEnumProperties);
    148    
     137    ASSERT(propertyNames.size() < UINT32_MAX);
     138
    149139    normalizePrototypeChain(exec, structure);
    150140
    151     JSPropertyNameEnumerator* enumerator = JSPropertyNameEnumerator::create(vm, base->structure(vm), propertyNames);
     141    enumerator = JSPropertyNameEnumerator::create(vm, structure, indexedLength, numberStructureProperties, propertyNames);
    152142    enumerator->setCachedPrototypeChain(vm, structure->prototypeChain(exec));
    153     if (!length && structure->canCacheGenericPropertyNameEnumerator())
    154         structure->setCachedGenericPropertyNameEnumerator(vm, enumerator);
     143    if (!indexedLength && structure->canCachePropertyNameEnumerator())
     144        structure->setCachedPropertyNameEnumerator(vm, enumerator);
    155145    return enumerator;
    156146}
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r181867 r181891  
    12171217}
    12181218
    1219 void Structure::setCachedStructurePropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
     1219void Structure::setCachedPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
    12201220{
    12211221    ASSERT(!isDictionary());
    12221222    if (!hasRareData())
    12231223        allocateRareData(vm);
    1224     rareData()->setCachedStructurePropertyNameEnumerator(vm, enumerator);
    1225 }
    1226 
    1227 JSPropertyNameEnumerator* Structure::cachedStructurePropertyNameEnumerator() const
     1224    rareData()->setCachedPropertyNameEnumerator(vm, enumerator);
     1225}
     1226
     1227JSPropertyNameEnumerator* Structure::cachedPropertyNameEnumerator() const
    12281228{
    12291229    if (!hasRareData())
    12301230        return nullptr;
    1231     return rareData()->cachedStructurePropertyNameEnumerator();
    1232 }
    1233 
    1234 void Structure::setCachedGenericPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
    1235 {
    1236     ASSERT(!isDictionary());
    1237     if (!hasRareData())
    1238         allocateRareData(vm);
    1239     rareData()->setCachedGenericPropertyNameEnumerator(vm, enumerator);
    1240 }
    1241 
    1242 JSPropertyNameEnumerator* Structure::cachedGenericPropertyNameEnumerator() const
    1243 {
    1244     if (!hasRareData())
    1245         return nullptr;
    1246     return rareData()->cachedGenericPropertyNameEnumerator();
    1247 }
    1248 
    1249 bool Structure::canCacheStructurePropertyNameEnumerator() const
     1231    return rareData()->cachedPropertyNameEnumerator();
     1232}
     1233
     1234bool Structure::canCachePropertyNameEnumerator() const
    12501235{
    12511236    if (isDictionary())
    1252         return false;
    1253     return true;
    1254 }
    1255 
    1256 bool Structure::canCacheGenericPropertyNameEnumerator() const
    1257 {
    1258     if (!canCacheStructurePropertyNameEnumerator())
    12591237        return false;
    12601238
     
    12751253        structure++;
    12761254    }
    1277 
     1255   
    12781256    return true;
    12791257}
    1280 
     1258   
    12811259bool Structure::canAccessPropertiesQuickly() const
    12821260{
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r176583 r181891  
    316316    }
    317317
    318     void setCachedStructurePropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
    319     void setCachedGenericPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
    320     JSPropertyNameEnumerator* cachedStructurePropertyNameEnumerator() const;
    321     JSPropertyNameEnumerator* cachedGenericPropertyNameEnumerator() const;
    322     bool canCacheStructurePropertyNameEnumerator() const;
    323     bool canCacheGenericPropertyNameEnumerator() const;
     318    void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
     319    JSPropertyNameEnumerator* cachedPropertyNameEnumerator() const;
     320    bool canCachePropertyNameEnumerator() const;
    324321    bool canAccessPropertiesQuickly() const;
    325322
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp

    r172176 r181891  
    6767    visitor.append(&thisObject->m_previous);
    6868    visitor.append(&thisObject->m_objectToStringValue);
    69     visitor.append(&thisObject->m_cachedStructurePropertyNameEnumerator);
     69    visitor.append(&thisObject->m_cachedPropertyNameEnumerator);
    7070    visitor.append(&thisObject->m_cachedGenericPropertyNameEnumerator);
    7171}
    7272
    73 JSPropertyNameEnumerator* StructureRareData::cachedStructurePropertyNameEnumerator() const
     73JSPropertyNameEnumerator* StructureRareData::cachedPropertyNameEnumerator() const
    7474{
    75     return m_cachedStructurePropertyNameEnumerator.get();
     75    return m_cachedPropertyNameEnumerator.get();
    7676}
    7777
    78 void StructureRareData::setCachedStructurePropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
     78void StructureRareData::setCachedPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
    7979{
    80     m_cachedStructurePropertyNameEnumerator.set(vm, this, enumerator);
    81 }
    82 
    83 JSPropertyNameEnumerator* StructureRareData::cachedGenericPropertyNameEnumerator() const
    84 {
    85     return m_cachedGenericPropertyNameEnumerator.get();
    86 }
    87 
    88 void StructureRareData::setCachedGenericPropertyNameEnumerator(VM& vm, JSPropertyNameEnumerator* enumerator)
    89 {
    90     m_cachedGenericPropertyNameEnumerator.set(vm, this, enumerator);
     80    m_cachedPropertyNameEnumerator.set(vm, this, enumerator);
    9181}
    9282
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.h

    r172176 r181891  
    5656    void setObjectToStringValue(VM&, JSString* value);
    5757
    58     JSPropertyNameEnumerator* cachedStructurePropertyNameEnumerator() const;
    59     JSPropertyNameEnumerator* cachedGenericPropertyNameEnumerator() const;
    60     void setCachedStructurePropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
    61     void setCachedGenericPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
     58    JSPropertyNameEnumerator* cachedPropertyNameEnumerator() const;
     59    void setCachedPropertyNameEnumerator(VM&, JSPropertyNameEnumerator*);
    6260
    6361    DECLARE_EXPORT_INFO;
     
    7270    WriteBarrier<Structure> m_previous;
    7371    WriteBarrier<JSString> m_objectToStringValue;
    74     WriteBarrier<JSPropertyNameEnumerator> m_cachedStructurePropertyNameEnumerator;
     72    WriteBarrier<JSPropertyNameEnumerator> m_cachedPropertyNameEnumerator;
    7573    WriteBarrier<JSPropertyNameEnumerator> m_cachedGenericPropertyNameEnumerator;
    7674   
  • trunk/Source/JavaScriptCore/tests/stress/for-in-delete-during-iteration.js

    r172176 r181891  
    3737    noInline(foo);
    3838    for (var i = 0; i < 10000; ++i) {
    39         // Note: it's undefined whether we visit o.a or not. Currently we do.
    40         if (foo() !== "xza")
     39        if (foo() !== "xz")
    4140            throw new Error("bad result");
    4241    }
Note: See TracChangeset for help on using the changeset viewer.