1. 25 Jul, 2013 5 commits
    • oliver@apple.com's avatar
      fourthTier: DFG shouldn't create CheckStructures for array accesses except if... · 58cdc336
      oliver@apple.com authored
      fourthTier: DFG shouldn't create CheckStructures for array accesses except if the ArrayMode implies an original array access
      https://bugs.webkit.org/show_bug.cgi?id=118867
      
      Reviewed by Mark Hahnenberg.
      
      This allows us to kill off a bunch of code in the parser, in fixup, and to simplify
      ArrayProfile.
      
      It also makes it easier to ask any array-using node how to create its type check.
      
      Doing this required fixing a bug in LowLevelInterpreter64, where it was storing into
      an array profile, thinking that it was storing into a value profile. Reshuffling the
      fields in ArrayProfile revealed this.
      
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescriptionWithoutUpdating):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::ArrayProfile):
      (ArrayProfile):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::updateAllArrayPredictions):
      (JSC::CodeBlock::updateAllPredictions):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::updateAllArrayPredictions):
      * dfg/DFGArrayMode.h:
      (ArrayMode):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getArrayModeConsideringSlowPath):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (FixupPhase):
      (JSC::DFG::FixupPhase::checkArray):
      (JSC::DFG::FixupPhase::blessArrayOperation):
      * llint/LowLevelInterpreter64.asm:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153281 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      58cdc336
    • oliver@apple.com's avatar
      fourthTier: DFG::AbstractState::beginBasicBlock() should set m_haveStructures... · 06cf1a8b
      oliver@apple.com authored
      fourthTier: DFG::AbstractState::beginBasicBlock() should set m_haveStructures if any of the valuesAtHead have either a current known structure or a non-top/non-bottom array modes
      https://bugs.webkit.org/show_bug.cgi?id=118489
      
      Reviewed by Mark Hahnenberg.
      
      * bytecode/ArrayProfile.h:
      (JSC::arrayModesAreClearOrTop):
      (JSC):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::beginBasicBlock):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::hasClobberableState):
      (AbstractValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153271 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      06cf1a8b
    • oliver@apple.com's avatar
      fourthTier: Have fewer Arrayify's · 4cd40f2e
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118335
      
      Reviewed by Mark Hahnenberg.
      
      A lot of Arrayify's arise because some program saw Int32 arrays early on in
      execution, but then they all got converted to Double arrays and the program
      will never see Int32 arrays ever again. Prior to this change you would always
      have an Arrayify in this case. But with this change, the first time that an
      ArrayProfile is about to go polymorphic in computeUpdatedPrediction(), it
      instead forcibly monomorphises itself to the latest-seen structure.
      Thereafter it will never again perform this monomorphisation. This is
      controlled by ArrayProfile::m_didPerformFirstRunPruning. This is a 5%
      speed-up on Kraken/imaging-gaussian-blur with the FTL enabled, and it
      unblocks a bunch of stuff we want to do in the future because it makes a
      bunch of loops effect-free.
      
      We will still want to implement Arrayify hoisting in the future, but this is
      great anyway because it's better to not have Arrayifications than it is to
      have hoisted Arrayifications.
      
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescription):
      (JSC):
      (JSC::ArrayProfile::briefDescriptionWithoutUpdating):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::ArrayProfile):
      (ArrayProfile):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153264 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4cd40f2e
    • oliver@apple.com's avatar
      fourthTier: should use ConcurrentJITLock[er] directly and not through typedef · d205666b
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116561
      
      Rubber stamped by Geoffrey Garen.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescription):
      * bytecode/ArrayProfile.h:
      (ArrayProfile):
      (JSC::ArrayProfile::expectedStructure):
      (JSC::ArrayProfile::structureIsPolymorphic):
      (JSC::ArrayProfile::hasDefiniteStructure):
      (JSC::ArrayProfile::observedArrayModes):
      (JSC::ArrayProfile::mayInterceptIndexedAccesses):
      (JSC::ArrayProfile::mayStoreToHole):
      (JSC::ArrayProfile::outOfBounds):
      (JSC::ArrayProfile::usesOriginalArrayStructures):
      * bytecode/CallLinkStatus.cpp:
      (JSC::CallLinkStatus::computeFor):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpValueProfiling):
      (JSC::CodeBlock::dumpArrayProfiling):
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      (JSC::CodeBlock::updateAllArrayPredictions):
      (JSC::CodeBlock::nameForRegister):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset):
      (CodeBlock):
      * bytecode/CodeBlockLock.h: Removed.
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor):
      * bytecode/LazyOperandValueProfile.cpp:
      (JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions):
      (JSC::CompressedLazyOperandValueProfileHolder::add):
      (JSC::LazyOperandValueProfileParser::initialize):
      (JSC::LazyOperandValueProfileParser::prediction):
      * bytecode/LazyOperandValueProfile.h:
      (CompressedLazyOperandValueProfileHolder):
      (LazyOperandValueProfileParser):
      * bytecode/MethodOfGettingAValueProfile.cpp:
      (JSC::MethodOfGettingAValueProfile::getSpecFailBucket):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor):
      * bytecode/ResolveGlobalStatus.cpp:
      (JSC::ResolveGlobalStatus::computeFor):
      * bytecode/ValueProfile.h:
      (JSC::ValueProfileBase::briefDescription):
      (JSC::ValueProfileBase::computeUpdatedPrediction):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::addVar):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::fromObserved):
      * dfg/DFGArrayMode.h:
      (ArrayMode):
      (JSC::DFG::ArrayMode::withProfile):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
      (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
      (JSC::DFG::ByteCodeParser::getArrayMode):
      (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * jit/JITInlines.h:
      (JSC::JIT::chooseArrayMode):
      * jit/JITStubs.cpp:
      (JSC::tryCachePutByID):
      (JSC::tryCacheGetByID):
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::lazyLinkFor):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      (JSC::LLInt::setUpCall):
      * profiler/ProfilerBytecodeSequence.cpp:
      (JSC::Profiler::BytecodeSequence::BytecodeSequence):
      * runtime/Executable.cpp:
      (JSC::ProgramExecutable::addGlobalVar):
      * runtime/JSActivation.cpp:
      (JSC::JSActivation::getOwnNonIndexPropertyNames):
      (JSC::JSActivation::symbolTablePutWithAttributes):
      * runtime/JSScope.cpp:
      (JSC::JSScope::resolveContainingScopeInternal):
      (JSC::JSScope::resolvePut):
      * runtime/JSSegmentedVariableObject.cpp:
      (JSC::JSSegmentedVariableObject::findRegisterIndex):
      (JSC::JSSegmentedVariableObject::addRegisters):
      * runtime/JSSegmentedVariableObject.h:
      (JSSegmentedVariableObject):
      * runtime/JSSymbolTableObject.cpp:
      (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
      * runtime/JSSymbolTableObject.h:
      (JSC::symbolTableGet):
      (JSC::symbolTablePut):
      (JSC::symbolTablePutWithAttributes):
      * runtime/Structure.cpp:
      (JSC::Structure::materializePropertyMap):
      (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
      (JSC::Structure::addPropertyTransition):
      (JSC::Structure::takePropertyTableOrCloneIfPinned):
      (JSC::Structure::nonPropertyTransition):
      (JSC::Structure::putSpecificValue):
      (JSC::Structure::remove):
      (JSC::Structure::createPropertyMap):
      * runtime/Structure.h:
      (Structure):
      * runtime/SymbolTable.h:
      (SymbolTable):
      (JSC::SymbolTable::find):
      (JSC::SymbolTable::get):
      (JSC::SymbolTable::inlineGet):
      (JSC::SymbolTable::begin):
      (JSC::SymbolTable::end):
      (JSC::SymbolTable::size):
      (JSC::SymbolTable::add):
      (JSC::SymbolTable::set):
      (JSC::SymbolTable::contains):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153170 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d205666b
    • oliver@apple.com's avatar
      fourthTier: value profiles and array profiles should be thread-safe enough to... · c14eb7d0
      oliver@apple.com authored
      fourthTier: value profiles and array profiles should be thread-safe enough to be accessible in a concurrent compilation thread
      https://bugs.webkit.org/show_bug.cgi?id=114906
      
      Source/JavaScriptCore:
      
      Reviewed by Oliver Hunt.
      
      This introduces thread safety to value profiles, array profiles, and
      array allocation profiles.
      
      We already have three separate operations that happen on profiles:
      (1) writing, which the JIT, LLInt, and OSR exit do; (2) updating,
      which happens during GC, from OSR entry slow-paths, and in the DFG;
      and (3) reading, which happens in the DFG. For example, the JIT/LLInt
      and OSR exit write to ValueProfile::m_buckets, which gets synthesized
      into ValueProfile::m_prediction (and other fields) during update, and
      the latter gets read by the DFG. Note that (2) must also happen in
      the DFG since only the DFG knows which code blocks it will inline,
      and those blocks' profiles may not have otherwise been updated via
      any other mechanism.
      
      I refer to these three operations as writing, updating, and reading.
      
      Consequently, both profile updating and profile reading may happen
      asynchronously, if the JIT is asynchronous.
      
      The locking protocol for profiles works as follows:
      
      - Writing does not require locking, but is only allowed on the main
        thread. We require that these fields can be stored atomically by
        the profiling code, even without locks. For value profiles, this
        only works on 64-bit platforms, currently. For array profiles,
        which consist of multiple separate fields, this means that an
        asynchronous update of the profile may see slight inconsistencies
        (like a structure that doesn't quite match the array modes bits),
        but these should be harmless: at worst, the DFG will specialize
        too much and we'll have OSR exits.
      
      - Updating a value profile requires holding a lock, but must assume
        that the fields written by the profiling code in JIT/LLInt may
        be written to without locking.
      
      - Reading a value profile requires holding a lock.
      
      The one major exception to these rules is the ArrayAllocationProfile,
      which requires no locking. We do this because it's used so often and
      in places where we don't necessarily have access to the owning
      CodeBlock, so if we did want it to be locked it would have to have
      its own lock. Also, I believe that it is sound to just make this
      profile racy and not worry about locking at all. All that was needed
      were some changes to ensure that we explicitly read some raced-over
      fields only once.
      
      Two additional interesting things in this change:
      
      - To make it easy to see which profile methods require locking, they
        take a const CodeBlockLocker& as an argument. I saw this idiom for
        identifying which methods require which locks to be held being used
        in LLVM, and I quite like it.
      
      - Lazy operand value profiles, which are created lazily and at any
        time, require the CodeBlockLock to be held when they are being
        created. Writes to them are lockless and main-thread-only, but as
        with other profiles, updates and reads require locking.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/ArrayAllocationProfile.cpp:
      (JSC::ArrayAllocationProfile::updateIndexingType):
      * bytecode/ArrayAllocationProfile.h:
      (JSC::ArrayAllocationProfile::selectIndexingType):
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescription):
      * bytecode/ArrayProfile.h:
      (ArrayProfile):
      (JSC::ArrayProfile::expectedStructure):
      (JSC::ArrayProfile::structureIsPolymorphic):
      (JSC::ArrayProfile::hasDefiniteStructure):
      (JSC::ArrayProfile::observedArrayModes):
      (JSC::ArrayProfile::mayInterceptIndexedAccesses):
      (JSC::ArrayProfile::mayStoreToHole):
      (JSC::ArrayProfile::outOfBounds):
      (JSC::ArrayProfile::usesOriginalArrayStructures):
      * bytecode/CallLinkStatus.cpp:
      (JSC::CallLinkStatus::computeFor):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpValueProfiling):
      (JSC::CodeBlock::dumpArrayProfiling):
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      (JSC::CodeBlock::updateAllArrayPredictions):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset):
      (JSC::CodeBlock::updateAllPredictionsAndCheckIfShouldOptimizeNow):
      (CodeBlock):
      * bytecode/CodeBlockLock.h: Added.
      (JSC):
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor):
      * bytecode/LazyOperandValueProfile.cpp:
      (JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions):
      (JSC::CompressedLazyOperandValueProfileHolder::add):
      (JSC::LazyOperandValueProfileParser::LazyOperandValueProfileParser):
      (JSC::LazyOperandValueProfileParser::~LazyOperandValueProfileParser):
      (JSC):
      (JSC::LazyOperandValueProfileParser::initialize):
      (JSC::LazyOperandValueProfileParser::prediction):
      * bytecode/LazyOperandValueProfile.h:
      (CompressedLazyOperandValueProfileHolder):
      (LazyOperandValueProfileParser):
      * bytecode/MethodOfGettingAValueProfile.cpp:
      (JSC::MethodOfGettingAValueProfile::getSpecFailBucket):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor):
      * bytecode/ResolveGlobalStatus.cpp:
      (JSC::ResolveGlobalStatus::computeFor):
      * bytecode/ValueProfile.h:
      (JSC::ValueProfileBase::briefDescription):
      (ValueProfileBase):
      (JSC::ValueProfileBase::computeUpdatedPrediction):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::fromObserved):
      * dfg/DFGArrayMode.h:
      (ArrayMode):
      (JSC::DFG::ArrayMode::withProfile):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation):
      (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
      (JSC::DFG::ByteCodeParser::getArrayMode):
      (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
      (JSC::DFG::ByteCodeParser::parseResolveOperations):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGOSRExitPreparation.cpp:
      (JSC::DFG::prepareCodeOriginForOSRExit):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * jit/JITInlines.h:
      (JSC::JIT::chooseArrayMode):
      * jit/JITStubs.cpp:
      (JSC::tryCachePutByID):
      (JSC::tryCacheGetByID):
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::lazyLinkFor):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      (JSC::LLInt::setUpCall):
      * profiler/ProfilerBytecodeSequence.cpp:
      (JSC::Profiler::BytecodeSequence::BytecodeSequence):
      * runtime/JSScope.cpp:
      (JSC::JSScope::resolveContainingScopeInternal):
      (JSC::JSScope::resolvePut):
      
      Source/WTF:
      
      Reviewed by Oliver Hunt.
      
      Add ability to abstract whether or not the CodeBlock requires locking at all,
      since some platforms may not support the byte spin-locking and/or may not want
      to, if they turn off concurrent JIT.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/ByteSpinLock.h:
      * wtf/NoLock.h: Added.
      (WTF):
      (NoLock):
      (WTF::NoLock::lock):
      (WTF::NoLock::unlock):
      (WTF::NoLock::isHeld):
      * wtf/Platform.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153123 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c14eb7d0
  2. 09 May, 2013 1 commit
    • mhahnenberg@apple.com's avatar
      DFGArrayMode::fromObserved is too liberal when it sees different Array and NonArray shapes · 3ebd59e4
      mhahnenberg@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=115805
      
      Source/JavaScriptCore: 
      
      Reviewed by Geoffrey Garen.
      
      It checks the observed ArrayModes to see if we have seen any ArrayWith* first. If so, it assumes it's 
      an Array::Array, even if we've also observed any NonArrayWith* in the ArrayProfile. This leads to the 
      code generated by jumpSlowForUnwantedArrayMode to check the indexing type against (shape | IsArray) 
      instead of just shape, which can cause us to exit a lot in the case that we saw a NonArray.
      
      To fix this we need to add a case that checks for both ArrayWith* and NonArrayWith* cases first, which 
      should then use Array::PossiblyArray, then do the checks we were already doing.
      
      * bytecode/ArrayProfile.h:
      (JSC::hasSeenArray):
      (JSC::hasSeenNonArray):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::fromObserved):
      
      LayoutTests: 
      
      Added regression test for array access over polymorphic array vs. non-array indexing types.
      With the fix, we get 3.666x faster on this microbenchmark.
      
      Reviewed by Geoffrey Garen.
      
      * fast/js/regress/array-nonarray-polymorphic-access-expected.txt: Added.
      * fast/js/regress/array-nonarray-polymorphic-access.html: Added.
      * fast/js/regress/script-tests/array-nonarray-polymorphic-access.js: Added.
      (f):
      (run):
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@149834 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      3ebd59e4
  3. 17 Dec, 2012 1 commit
    • fpizlo@apple.com's avatar
      Rationalize array profiling for out-of-bounds and hole cases · 304fbcaa
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=105139
      
      Reviewed by Geoffrey Garen.
      
      This makes ArrayProfile track whether or not we had out-of-bounds, which allows
      for more precise decision-making in the DFG.
              
      Also cleaned up ExitKinds for out-of-bounds and hole cases to make it easier to
      look at them in the profiler.
              
      Slight speed-up (5-8%) on SunSpider/crypto-md5.
      
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      (JSC::ArrayProfile::briefDescription):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::ArrayProfile):
      (JSC::ArrayProfile::addressOfOutOfBounds):
      (JSC::ArrayProfile::expectedStructure):
      (JSC::ArrayProfile::structureIsPolymorphic):
      (JSC::ArrayProfile::outOfBounds):
      (JSC::ArrayProfile::polymorphicStructure):
      * bytecode/CodeBlock.cpp:
      (JSC::dumpChain):
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      (JSC::exitKindIsCountable):
      * bytecode/ExitKind.h:
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * jit/JIT.h:
      * jit/JITInlines.h:
      (JSC::JIT::emitArrayProfileOutOfBoundsSpecialCase):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emitSlow_op_get_by_val):
      (JSC::JIT::emitSlow_op_put_by_val):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emitSlow_op_get_by_val):
      (JSC::JIT::emitSlow_op_put_by_val):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@137937 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      304fbcaa
  4. 12 Dec, 2012 1 commit
    • fpizlo@apple.com's avatar
      Profiler should show bytecode dumps as they would have been visible to the... · 77ef0e33
      fpizlo@apple.com authored
      Profiler should show bytecode dumps as they would have been visible to the JITs, including the profiling data that the JITs would see
      https://bugs.webkit.org/show_bug.cgi?id=104647
      
      Reviewed by Oliver Hunt.
      
      Source/JavaScriptCore: 
      
      Adds more profiling data to bytecode dumps, and adds the ability to do a secondary
      bytecode dump for each JIT compilation of a code block. This is relevant because both
      the bytecodes, and the profiling data, may change after some number of executions.
              
      Also fixes some random dumping code to use PrintStream& rather than
      static const char[thingy].
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/ArrayProfile.cpp:
      (JSC::dumpArrayModes):
      (JSC::ArrayProfile::briefDescription):
      * bytecode/ArrayProfile.h:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::printGetByIdOp):
      (JSC::CodeBlock::printGetByIdCacheStatus):
      (JSC::CodeBlock::printCallOp):
      (JSC::CodeBlock::dumpValueProfiling):
      (JSC::CodeBlock::dumpArrayProfiling):
      (JSC::CodeBlock::dumpBytecode):
      * bytecode/CodeBlock.h:
      * bytecode/ValueProfile.h:
      (JSC::ValueProfileBase::briefDescription):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::dump):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseCodeBlock):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompile):
      * profiler/ProfilerBytecodeSequence.cpp: Added.
      (JSC::Profiler::BytecodeSequence::BytecodeSequence):
      (JSC::Profiler::BytecodeSequence::~BytecodeSequence):
      (JSC::Profiler::BytecodeSequence::indexForBytecodeIndex):
      (JSC::Profiler::BytecodeSequence::forBytecodeIndex):
      (JSC::Profiler::BytecodeSequence::addSequenceProperties):
      * profiler/ProfilerBytecodeSequence.h: Added.
      (JSC::Profiler::BytecodeSequence::size):
      (JSC::Profiler::BytecodeSequence::at):
      * profiler/ProfilerBytecodes.cpp:
      (JSC::Profiler::Bytecodes::Bytecodes):
      (JSC::Profiler::Bytecodes::toJS):
      * profiler/ProfilerBytecodes.h:
      (JSC::Profiler::Bytecodes::instructionCount):
      * profiler/ProfilerCompilation.cpp:
      (JSC::Profiler::Compilation::addProfiledBytecodes):
      (JSC::Profiler::Compilation::toJS):
      * profiler/ProfilerCompilation.h:
      (JSC::Profiler::Compilation::profiledBytecodesSize):
      (JSC::Profiler::Compilation::profiledBytecodesAt):
      * profiler/ProfilerDatabase.cpp:
      (JSC::Profiler::Database::ensureBytecodesFor):
      * profiler/ProfilerDatabase.h:
      * profiler/ProfilerProfiledBytecodes.cpp: Added.
      (JSC::Profiler::ProfiledBytecodes::ProfiledBytecodes):
      (JSC::Profiler::ProfiledBytecodes::~ProfiledBytecodes):
      (JSC::Profiler::ProfiledBytecodes::toJS):
      * profiler/ProfilerProfiledBytecodes.h: Added.
      (JSC::Profiler::ProfiledBytecodes::bytecodes):
      * runtime/CommonIdentifiers.h:
      
      Tools: 
      
      Added a "profiling" (or "p") command to show the profiling data that the JITs saw
      for each JIT compilation of a code block.
              
      Also added instruction counts in the "full" display and made the "full" display the
      default thing you see.
      
      * Scripts/display-profiler-output:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@137379 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      77ef0e33
  5. 08 Nov, 2012 1 commit
    • fpizlo@apple.com's avatar
      JSC should infer when indexed storage contains only integers or doubles · 75c91a79
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=98606
      
      Reviewed by Oliver Hunt.
      
      Source/JavaScriptCore: 
      
      This adds two new indexing types: int32 and double. It also adds array allocation profiling,
      which allows array allocations to converge to allocating arrays using those types to which
      those arrays would have been converted.
              
      20% speed-up on navier-stokes. 40% speed-up on various Kraken DSP tests. Some slow-downs too,
      but a performance win overall on all benchmarks we track.
      
      * API/JSObjectRef.cpp:
      (JSObjectMakeArray):
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * assembler/AbstractMacroAssembler.h:
      (JumpList):
      (JSC::AbstractMacroAssembler::JumpList::JumpList):
      * assembler/MacroAssemblerX86Common.h:
      (JSC::MacroAssemblerX86Common::branchDouble):
      * assembler/X86Assembler.h:
      (JSC::X86Assembler::jnp):
      (X86Assembler):
      (JSC::X86Assembler::X86InstructionFormatter::emitRex):
      * bytecode/ArrayAllocationProfile.cpp: Added.
      (JSC):
      (JSC::ArrayAllocationProfile::updateIndexingType):
      * bytecode/ArrayAllocationProfile.h: Added.
      (JSC):
      (ArrayAllocationProfile):
      (JSC::ArrayAllocationProfile::ArrayAllocationProfile):
      (JSC::ArrayAllocationProfile::selectIndexingType):
      (JSC::ArrayAllocationProfile::updateLastAllocation):
      (JSC::ArrayAllocationProfile::selectIndexingTypeFor):
      (JSC::ArrayAllocationProfile::updateLastAllocationFor):
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::updatedObservedArrayModes):
      (JSC):
      * bytecode/ArrayProfile.h:
      (JSC):
      (JSC::arrayModesInclude):
      (JSC::shouldUseSlowPutArrayStorage):
      (JSC::shouldUseFastArrayStorage):
      (JSC::shouldUseContiguous):
      (JSC::shouldUseDouble):
      (JSC::shouldUseInt32):
      (ArrayProfile):
      * bytecode/ByValInfo.h:
      (JSC::isOptimizableIndexingType):
      (JSC::jitArrayModeForIndexingType):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dump):
      (JSC::CodeBlock::CodeBlock):
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      (JSC):
      (JSC::CodeBlock::updateAllValueProfilePredictions):
      (JSC::CodeBlock::updateAllArrayPredictions):
      (JSC::CodeBlock::updateAllPredictions):
      (JSC::CodeBlock::shouldOptimizeNow):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::numberOfArrayAllocationProfiles):
      (JSC::CodeBlock::addArrayAllocationProfile):
      (JSC::CodeBlock::updateAllValueProfilePredictions):
      (JSC::CodeBlock::updateAllArrayPredictions):
      * bytecode/DFGExitProfile.h:
      (JSC::DFG::exitKindToString):
      * bytecode/Instruction.h:
      (JSC):
      (JSC::Instruction::Instruction):
      * bytecode/Opcode.h:
      (JSC):
      (JSC::padOpcodeName):
      * bytecode/SpeculatedType.h:
      (JSC):
      (JSC::isRealNumberSpeculation):
      * bytecode/UnlinkedCodeBlock.cpp:
      (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
      * bytecode/UnlinkedCodeBlock.h:
      (JSC):
      (JSC::UnlinkedCodeBlock::addArrayAllocationProfile):
      (JSC::UnlinkedCodeBlock::numberOfArrayAllocationProfiles):
      (UnlinkedCodeBlock):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::newArrayAllocationProfile):
      (JSC):
      (JSC::BytecodeGenerator::emitNewArray):
      (JSC::BytecodeGenerator::emitExpectedFunctionSnippet):
      * bytecompiler/BytecodeGenerator.h:
      (BytecodeGenerator):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::fromObserved):
      (JSC::DFG::ArrayMode::refine):
      (DFG):
      (JSC::DFG::ArrayMode::alreadyChecked):
      (JSC::DFG::arrayTypeToString):
      * dfg/DFGArrayMode.h:
      (JSC::DFG::ArrayMode::withType):
      (ArrayMode):
      (JSC::DFG::ArrayMode::withTypeAndConversion):
      (JSC::DFG::ArrayMode::usesButterfly):
      (JSC::DFG::ArrayMode::isSpecific):
      (JSC::DFG::ArrayMode::supportsLength):
      (JSC::DFG::ArrayMode::arrayModesThatPassFiltering):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getArrayMode):
      (ByteCodeParser):
      (JSC::DFG::ByteCodeParser::handleIntrinsic):
      (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCCallHelpers.h:
      (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
      (CCallHelpers):
      * dfg/DFGCallArrayAllocatorSlowPathGenerator.h:
      (JSC::DFG::CallArrayAllocatorSlowPathGenerator::generateInternal):
      (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::generateInternal):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::checkArray):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::byValIsPure):
      * dfg/DFGNode.h:
      (NewArrayBufferData):
      (JSC::DFG::Node::hasIndexingType):
      (Node):
      (JSC::DFG::Node::indexingType):
      (JSC::DFG::Node::setIndexingType):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::emitAllocateJSArray):
      (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
      (DFG):
      (JSC::DFG::SpeculativeJIT::checkArray):
      (JSC::DFG::SpeculativeJIT::arrayify):
      (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
      (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      (SpeculativeJIT):
      (SpeculateIntegerOperand):
      (JSC::DFG::SpeculateIntegerOperand::use):
      (SpeculateDoubleOperand):
      (JSC::DFG::SpeculateDoubleOperand::use):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (DFG):
      (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * jit/JIT.h:
      (JSC::JIT::emitInt32GetByVal):
      (JIT):
      (JSC::JIT::emitInt32PutByVal):
      (JSC::JIT::emitDoublePutByVal):
      (JSC::JIT::emitContiguousPutByVal):
      * jit/JITExceptions.cpp:
      (JSC::genericThrow):
      * jit/JITInlineMethods.h:
      (JSC::arrayProfileSaw):
      (JSC::JIT::chooseArrayMode):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_new_array):
      (JSC::JIT::emit_op_new_array_with_size):
      (JSC::JIT::emit_op_new_array_buffer):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emitDoubleGetByVal):
      (JSC):
      (JSC::JIT::emitContiguousGetByVal):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::emitGenericContiguousPutByVal):
      (JSC::JIT::emitSlow_op_put_by_val):
      (JSC::JIT::privateCompileGetByVal):
      (JSC::JIT::privateCompilePutByVal):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emitContiguousGetByVal):
      (JSC::JIT::emitDoubleGetByVal):
      (JSC):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::emitGenericContiguousPutByVal):
      (JSC::JIT::emitSlow_op_put_by_val):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * jit/JITStubs.h:
      (JSC):
      * jsc.cpp:
      (GlobalObject::finishCreation):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::jitCompileAndSetHeuristics):
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      * offlineasm/x86.rb:
      * runtime/ArrayConstructor.cpp:
      (JSC::constructArrayWithSizeQuirk):
      * runtime/ArrayConstructor.h:
      (JSC):
      * runtime/ArrayPrototype.cpp:
      (JSC::arrayProtoFuncConcat):
      (JSC::arrayProtoFuncSlice):
      (JSC::arrayProtoFuncSplice):
      (JSC::arrayProtoFuncFilter):
      (JSC::arrayProtoFuncMap):
      * runtime/Butterfly.h:
      (JSC::Butterfly::contiguousInt32):
      (JSC::Butterfly::contiguousDouble):
      (JSC::Butterfly::fromContiguous):
      * runtime/ButterflyInlineMethods.h:
      (JSC::Butterfly::createUninitializedDuringCollection):
      * runtime/FunctionPrototype.cpp:
      (JSC::functionProtoFuncBind):
      * runtime/IndexingHeaderInlineMethods.h:
      (JSC::IndexingHeader::indexingPayloadSizeInBytes):
      * runtime/IndexingType.cpp:
      (JSC::leastUpperBoundOfIndexingTypes):
      (JSC):
      (JSC::leastUpperBoundOfIndexingTypeAndType):
      (JSC::leastUpperBoundOfIndexingTypeAndValue):
      (JSC::indexingTypeToString):
      * runtime/IndexingType.h:
      (JSC):
      (JSC::hasUndecided):
      (JSC::hasInt32):
      (JSC::hasDouble):
      * runtime/JSArray.cpp:
      (JSC::JSArray::setLength):
      (JSC::JSArray::pop):
      (JSC::JSArray::push):
      (JSC::JSArray::shiftCountWithAnyIndexingType):
      (JSC::JSArray::unshiftCountWithAnyIndexingType):
      (JSC::compareNumbersForQSortWithInt32):
      (JSC):
      (JSC::compareNumbersForQSortWithDouble):
      (JSC::JSArray::sortNumericVector):
      (JSC::JSArray::sortNumeric):
      (JSC::JSArray::sortCompactedVector):
      (JSC::JSArray::sort):
      (JSC::JSArray::sortVector):
      (JSC::JSArray::fillArgList):
      (JSC::JSArray::copyToArguments):
      (JSC::JSArray::compactForSorting):
      * runtime/JSArray.h:
      (JSArray):
      (JSC::createContiguousArrayButterfly):
      (JSC::JSArray::create):
      (JSC::JSArray::tryCreateUninitialized):
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::reset):
      (JSC):
      (JSC::JSGlobalObject::haveABadTime):
      (JSC::JSGlobalObject::visitChildren):
      * runtime/JSGlobalObject.h:
      (JSGlobalObject):
      (JSC::JSGlobalObject::originalArrayStructureForIndexingType):
      (JSC::JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation):
      (JSC::JSGlobalObject::arrayStructureForProfileDuringAllocation):
      (JSC::JSGlobalObject::isOriginalArrayStructure):
      (JSC::constructEmptyArray):
      (JSC::constructArray):
      * runtime/JSObject.cpp:
      (JSC::JSObject::copyButterfly):
      (JSC::JSObject::getOwnPropertySlotByIndex):
      (JSC::JSObject::putByIndex):
      (JSC::JSObject::enterDictionaryIndexingMode):
      (JSC::JSObject::createInitialIndexedStorage):
      (JSC):
      (JSC::JSObject::createInitialUndecided):
      (JSC::JSObject::createInitialInt32):
      (JSC::JSObject::createInitialDouble):
      (JSC::JSObject::createInitialContiguous):
      (JSC::JSObject::convertUndecidedToInt32):
      (JSC::JSObject::convertUndecidedToDouble):
      (JSC::JSObject::convertUndecidedToContiguous):
      (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
      (JSC::JSObject::convertUndecidedToArrayStorage):
      (JSC::JSObject::convertInt32ToDouble):
      (JSC::JSObject::convertInt32ToContiguous):
      (JSC::JSObject::convertInt32ToArrayStorage):
      (JSC::JSObject::convertDoubleToContiguous):
      (JSC::JSObject::convertDoubleToArrayStorage):
      (JSC::JSObject::convertContiguousToArrayStorage):
      (JSC::JSObject::convertUndecidedForValue):
      (JSC::JSObject::convertInt32ForValue):
      (JSC::JSObject::setIndexQuicklyToUndecided):
      (JSC::JSObject::convertInt32ToDoubleOrContiguousWhilePerformingSetIndex):
      (JSC::JSObject::convertDoubleToContiguousWhilePerformingSetIndex):
      (JSC::JSObject::ensureInt32Slow):
      (JSC::JSObject::ensureDoubleSlow):
      (JSC::JSObject::ensureContiguousSlow):
      (JSC::JSObject::ensureArrayStorageSlow):
      (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
      (JSC::JSObject::switchToSlowPutArrayStorage):
      (JSC::JSObject::deletePropertyByIndex):
      (JSC::JSObject::getOwnPropertyNames):
      (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
      (JSC::JSObject::putByIndexBeyondVectorLength):
      (JSC::JSObject::putDirectIndexBeyondVectorLength):
      (JSC::JSObject::getNewVectorLength):
      (JSC::JSObject::countElements):
      (JSC::JSObject::ensureLengthSlow):
      (JSC::JSObject::getOwnPropertyDescriptor):
      * runtime/JSObject.h:
      (JSC::JSObject::getArrayLength):
      (JSC::JSObject::getVectorLength):
      (JSC::JSObject::canGetIndexQuickly):
      (JSC::JSObject::getIndexQuickly):
      (JSC::JSObject::tryGetIndexQuickly):
      (JSC::JSObject::canSetIndexQuickly):
      (JSC::JSObject::canSetIndexQuicklyForPutDirect):
      (JSC::JSObject::setIndexQuickly):
      (JSC::JSObject::initializeIndex):
      (JSC::JSObject::hasSparseMap):
      (JSC::JSObject::inSparseIndexingMode):
      (JSObject):
      (JSC::JSObject::ensureInt32):
      (JSC::JSObject::ensureDouble):
      (JSC::JSObject::ensureLength):
      (JSC::JSObject::indexingData):
      (JSC::JSObject::currentIndexingData):
      (JSC::JSObject::getHolyIndexQuickly):
      (JSC::JSObject::relevantLength):
      (JSC::JSObject::currentRelevantLength):
      * runtime/JSValue.cpp:
      (JSC::JSValue::description):
      * runtime/LiteralParser.cpp:
      (JSC::::parse):
      * runtime/ObjectConstructor.cpp:
      (JSC::objectConstructorGetOwnPropertyNames):
      (JSC::objectConstructorKeys):
      * runtime/StringPrototype.cpp:
      (JSC::stringProtoFuncMatch):
      (JSC::stringProtoFuncSplit):
      * runtime/Structure.cpp:
      (JSC::Structure::nonPropertyTransition):
      * runtime/StructureTransitionTable.h:
      (JSC::newIndexingType):
      
      Source/WebCore: 
      
      Just refactoring WebCore to pass 0 for the ArrayAllocationProfile*.
      
      * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
      (WebCore::JSCanvasRenderingContext2D::webkitLineDash):
      * bindings/js/JSClipboardCustom.cpp:
      (WebCore::JSClipboard::types):
      * bindings/js/JSDOMBinding.cpp:
      (WebCore::jsArray):
      * bindings/js/JSDOMBinding.h:
      (WebCore::jsArray):
      * bindings/js/JSInjectedScriptHostCustom.cpp:
      (WebCore::getJSListenerFunctions):
      * bindings/js/JSJavaScriptCallFrameCustom.cpp:
      (WebCore::JSJavaScriptCallFrame::scopeChain):
      * bindings/js/JSMessageEventCustom.cpp:
      (WebCore::JSMessageEvent::ports):
      * bindings/js/JSMutationCallbackCustom.cpp:
      (WebCore::JSMutationCallback::handleEvent):
      * bindings/js/JSWebGLRenderingContextCustom.cpp:
      (WebCore::toJS):
      (WebCore::JSWebGLRenderingContext::getAttachedShaders):
      (WebCore::JSWebGLRenderingContext::getSupportedExtensions):
      * bindings/js/SerializedScriptValue.cpp:
      (WebCore::CloneDeserializer::deserialize):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@133953 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      75c91a79
  6. 29 Oct, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG should be able to emit effectful structure checks · 99f3762d
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=99260
      
      Reviewed by Oliver Hunt.
      
      This change allows us to find out if an array access that has gone polymorphic
      is operating over known structures - i.e. the primordial array structures of the
      global object that the code block containing the array access belongs to. We
      term this state "OriginalArray" for short. The fact that the access has gone
      polymorphic means that the array profile will not be able to report the set of
      structures it had seen - but if it can tell us that all of the structures were
      primordial then it just so happens that we can deduce what the structure set
      would have been by just querying the code block's global object. This allows us
      to emit an ArrayifyToStructure instead of an Arrayify if we find that we need to
      do conversions. The fast path of an ArrayifyToStructure is exactly like the fast
      path of a CheckStructure and is mostly subject to the same optimizations. It
      also burns one fewer registers.
              
      Essentially the notion of OriginalArray is a super cheap way of getting the
      array profile to tell us a structure set instead of a singleton structure.
      Currently, the array profile can only tell us the structure seen at an array
      access if there was exactly one structure. If there were multiple structures, it
      won't tell us anything other than the array modes and other auxiliary profiling
      data (whether there were stores to holes, for example). With OriginalArray, we
      cheaply get a structure set if all of the structures were primordial for the
      code block's global object, since in that case the array mode set (ArrayModes)
      can directly tell us the structure set. In the future, we might consider adding
      complete structure sets to the array profiles, but I suspect that we would hit
      diminishing returns if we did so - it would only help if we have array accesses
      that are both polymorphic and are cross-global-object accesses (rare) or if the
      arrays had named properties or other structure transitions that are unrelated to
      indexing type (also rare).
              
      This also does away with Arrayify (and the new ArrayifyToStructure) returning
      the butterfly pointer. This turns out to be faster and easier to CSE.
              
      And, this also changes constant folding to be able to eliminate CheckStructure,
      ForwardCheckStructure, and ArrayifyToStructure in addition to being able to
      transform them into structure transition watchpoints. This is great for
      ArrayifyToStructure because then CSE and CFA know that there is no side effect.
      Converting CheckStructure and ForwardCheckStructure to also behave this way is
      just a matter of elegance.
              
      This has no performance impact right now. It's intended to alleviate some of the
      regressions seen in the early implementation of
      https://bugs.webkit.org/show_bug.cgi?id=98606.
      
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      * bytecode/ArrayProfile.h:
      (JSC):
      (JSC::ArrayProfile::ArrayProfile):
      (ArrayProfile):
      (JSC::ArrayProfile::usesOriginalArrayStructures):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::fromObserved):
      (JSC::DFG::ArrayMode::alreadyChecked):
      (JSC::DFG::arrayClassToString):
      * dfg/DFGArrayMode.h:
      (JSC::DFG::ArrayMode::withProfile):
      (JSC::DFG::ArrayMode::isJSArray):
      (ArrayMode):
      (JSC::DFG::ArrayMode::isJSArrayWithOriginalStructure):
      (JSC::DFG::ArrayMode::supportsLength):
      (JSC::DFG::ArrayMode::arrayModesWithIndexingShape):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getArrayMode):
      (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
      (JSC::DFG::ByteCodeParser::handleGetByOffset):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::checkStructureElimination):
      (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination):
      (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
      (JSC::DFG::CSEPhase::checkArrayElimination):
      (JSC::DFG::CSEPhase::getScopeRegistersLoadElimination):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::checkArray):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::hasStructure):
      (JSC::DFG::Node::hasArrayMode):
      (JSC::DFG::Node::arrayMode):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
      (JSC::DFG::SpeculativeJIT::arrayify):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * runtime/JSGlobalObject.h:
      (JSC::JSGlobalObject::isOriginalArrayStructure):
      * runtime/Structure.cpp:
      (JSC::Structure::nonPropertyTransition):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@132759 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      99f3762d
  7. 20 Oct, 2012 1 commit
    • fpizlo@apple.com's avatar
      DFG should have some facility for recognizing redundant CheckArrays and Arrayifies · 372c6d51
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=99287
      
      Reviewed by Mark Hahnenberg.
      
      Adds reasoning about indexing type sets (i.e. ArrayModes) to AbstractValue, which
      then enables us to fold away CheckArray's and Arrayify's that are redundant.
      
      * bytecode/ArrayProfile.cpp:
      (JSC::arrayModesToString):
      (JSC):
      * bytecode/ArrayProfile.h:
      (JSC):
      (JSC::mergeArrayModes):
      (JSC::arrayModesAlreadyChecked):
      * bytecode/StructureSet.h:
      (JSC::StructureSet::arrayModesFromStructures):
      (StructureSet):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::AbstractValue):
      (JSC::DFG::AbstractValue::clear):
      (JSC::DFG::AbstractValue::isClear):
      (JSC::DFG::AbstractValue::makeTop):
      (JSC::DFG::AbstractValue::clobberStructures):
      (AbstractValue):
      (JSC::DFG::AbstractValue::setMostSpecific):
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::operator==):
      (JSC::DFG::AbstractValue::merge):
      (JSC::DFG::AbstractValue::filter):
      (JSC::DFG::AbstractValue::filterArrayModes):
      (JSC::DFG::AbstractValue::validate):
      (JSC::DFG::AbstractValue::checkConsistency):
      (JSC::DFG::AbstractValue::dump):
      (JSC::DFG::AbstractValue::clobberArrayModes):
      (JSC::DFG::AbstractValue::clobberArrayModesSlow):
      (JSC::DFG::AbstractValue::setFuturePossibleStructure):
      (JSC::DFG::AbstractValue::filterFuturePossibleStructure):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::modeAlreadyChecked):
      * dfg/DFGArrayMode.h:
      (JSC::DFG::arrayModesFor):
      (DFG):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::arrayify):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@131982 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      372c6d51
  8. 19 Sep, 2012 2 commits
    • fpizlo@apple.com's avatar
      DFG should not emit PutByVal hole case unless it has to · 69e2784d
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=97080
      
      Reviewed by Geoffrey Garen.
      
      This causes us to generate less code for typical PutByVal's. But if profiling tells us
      that the hole case is being hit, we generate the same code as we would have generated
      before. This seems like a slight speed-up across the board.
      
      * assembler/MacroAssemblerARMv7.h:
      (JSC::MacroAssemblerARMv7::store8):
      (MacroAssemblerARMv7):
      * assembler/MacroAssemblerX86.h:
      (MacroAssemblerX86):
      (JSC::MacroAssemblerX86::store8):
      * assembler/MacroAssemblerX86_64.h:
      (MacroAssemblerX86_64):
      (JSC::MacroAssemblerX86_64::store8):
      * assembler/X86Assembler.h:
      (X86Assembler):
      (JSC::X86Assembler::movb_i8m):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::ArrayProfile):
      (JSC::ArrayProfile::addressOfMayStoreToHole):
      (JSC::ArrayProfile::mayStoreToHole):
      (ArrayProfile):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::fromObserved):
      (JSC::DFG::modeAlreadyChecked):
      (JSC::DFG::modeToString):
      * dfg/DFGArrayMode.h:
      (DFG):
      (JSC::DFG::mayStoreToHole):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * jit/JIT.h:
      (JIT):
      * jit/JITInlineMethods.h:
      (JSC::JIT::emitArrayProfileStoreToHoleSpecialCase):
      (JSC):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emit_op_put_by_val):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emit_op_put_by_val):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@129045 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      69e2784d
    • fpizlo@apple.com's avatar
      DFG should not call out to C++ every time that it tries to put to an object... · 497c7515
      fpizlo@apple.com authored
      DFG should not call out to C++ every time that it tries to put to an object that doesn't yet have array storage
      https://bugs.webkit.org/show_bug.cgi?id=96983
      
      Reviewed by Oliver Hunt.
      
      Introduce more polymorphism into the DFG's array mode support. Use that to
      introduce the notion of effectul array modes, where the check for the mode
      will perform actions necessary to ensure that we have the mode we want, if
      the object is not already in that mode. Also added profiling support for
      checking if an object is of a type that would not allow us to create array
      storage (like a typed array or a string for example).
              
      This is a ~2x speed-up on loops that transform an object that did not have
      indexed storage into one that does.
      
      * JSCTypedArrayStubs.h:
      (JSC):
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::ArrayProfile):
      (JSC::ArrayProfile::mayInterceptIndexedAccesses):
      (ArrayProfile):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::fromObserved):
      (DFG):
      (JSC::DFG::modeAlreadyChecked):
      (JSC::DFG::modeToString):
      * dfg/DFGArrayMode.h:
      (DFG):
      (JSC::DFG::modeUsesButterfly):
      (JSC::DFG::isSlowPutAccess):
      (JSC::DFG::benefitsFromStructureCheck):
      (JSC::DFG::isEffectful):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::getArrayMode):
      (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::checkArray):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::byValIsPure):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::hasArrayMode):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::checkArray):
      (JSC::DFG::SpeculativeJIT::arrayify):
      (DFG):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * runtime/Arguments.h:
      (Arguments):
      * runtime/JSNotAnObject.h:
      (JSNotAnObject):
      * runtime/JSObject.h:
      (JSObject):
      (JSC::JSObject::ensureArrayStorage):
      * runtime/JSString.h:
      (JSC::JSString::createStructure):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@128957 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      497c7515
  9. 17 Sep, 2012 2 commits
    • fpizlo@apple.com's avatar
      If a prototype has indexed setters and its instances have indexed storage,... · 1c4a32c9
      fpizlo@apple.com authored
      If a prototype has indexed setters and its instances have indexed storage, then all put_by_val's should have a bad time
      https://bugs.webkit.org/show_bug.cgi?id=96596
      
      Reviewed by Gavin Barraclough.
      
      Source/JavaScriptCore: 
      
      Added comprehensive support for accessors and read-only indexed properties on the
      prototype chain. This is done without any performance regression on benchmarks that
      we're aware of, by having the entire VM's strategy with respect to arrays tilted
      heavily in favor of:
              
      - The prototype chain of JSArrays never having any accessors or read-only indexed
        properties. If that changes, you're going to have a bad time.
              
      - Prototypes of non-JSArray objects either having no indexed accessors or read-only
        indexed properties, or, having those indexed accessor thingies inserted before
        any instance object (i.e. object with that prototype as its prototype) is created.
        If you add indexed accessors or read-only indexed properties to an object that is
        already used as a prototype, you're going to have a bad time.
              
      See below for the exact definition of having a bad time.
              
      Put another way, "fair" uses of indexed accessors and read-only indexed properties
      are:
              
      - Put indexed accessors and read-only indexed properties on an object that is never
        used as a prototype. This will slow down accesses to that object, but will not
        have any effect on any other object.
              
      - Put those indexed accessor thingies on an object before it is used as a prototype
        and then start instantiating objects that claim that object as their prototype.
        This will slightly slow down indexed stores to the instance objects, and greatly
        slow down all indexed accesses to the prototype, but will have no other effect.
              
      In short, "fair" uses only affect the object itself and any instance objects. But
      if you start using indexed accessors in more eclectic ways, you're going to have
      a bad time.
              
      Specifically, if an object that may be used as a prototype has an indexed accessor
      added, the VM performs a whole-heap scan to find all objects that belong to the
      same global object as the prototype you modified. If any of those objects has
      indexed storage, their indexed storage is put into slow-put mode, just as if their
      prototype chain had indexed accessors. This will happen even for objects that do
      not currently have indexed accessors in their prototype chain. As well, all JSArray
      allocations are caused to create arrays with slow-put storage, and all future
      allocations of indexed storage for non-JSArray objects are also flipped to slow-put
      mode. Note there are two aspects to having a bad time: (i) the whole-heap scan and
      (ii) the poisoning of all indexed storage in the entire global object. (i) is
      necessary for correctness. If we detect that an object that may be used as a
      prototype has had an indexed accessor or indexed read-only property inserted into
      it, then we need to ensure that henceforth all instances of that object inspect
      the prototype chain whenever an indexed hole is stored to. But by default, indexed
      stores do no such checking because doing so would be unnecessarily slow. So, we must
      find all instances of the affected object and flip them into a different array
      storage mode that omits all hole optimizations. Since prototypes never keep a list
      of instance objects, the only way to find those objects is a whole-heap scan. But
      (i) alone would be a potential disaster, if a program frequently allocated an
      object without indexed accessors, then allocated a bunch of objects that used that
      one as their prototype, and then added indexed accessors to the prototype. So, to
      prevent massive heap scan storms in such awkward programs, having a bad time also
      implies (ii): henceforth *all* objects belonging to that global object will use
      slow put indexed storage, so that we don't ever have to scan the heap again. Note
      that here we are using the global object as just an approximation of a program
      module; it may be worth investigating in the future if other approximations can be
      used instead.
      
      * bytecode/ArrayProfile.h:
      (JSC):
      (JSC::arrayModeFromStructure):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::fromObserved):
      (JSC::DFG::modeAlreadyChecked):
      (JSC::DFG::modeToString):
      * dfg/DFGArrayMode.h:
      (DFG):
      (JSC::DFG::isSlowPutAccess):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::checkArray):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * jit/JIT.h:
      * jit/JITInlineMethods.h:
      (JSC::JIT::emitAllocateJSArray):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_new_array):
      * runtime/ArrayPrototype.cpp:
      (JSC::ArrayPrototype::finishCreation):
      (JSC::arrayProtoFuncSort):
      * runtime/IndexingType.h:
      (JSC):
      (JSC::hasIndexedProperties):
      (JSC::hasIndexingHeader):
      (JSC::hasArrayStorage):
      (JSC::shouldUseSlowPut):
      * runtime/JSArray.cpp:
      (JSC::JSArray::pop):
      (JSC::JSArray::push):
      (JSC::JSArray::fillArgList):
      (JSC::JSArray::copyToArguments):
      * runtime/JSArray.h:
      (JSC::JSArray::createStructure):
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::JSGlobalObject):
      (JSC::JSGlobalObject::reset):
      (JSC):
      (JSC::JSGlobalObject::haveABadTime):
      * runtime/JSGlobalObject.h:
      (JSGlobalObject):
      (JSC::JSGlobalObject::addressOfArrayStructure):
      (JSC::JSGlobalObject::havingABadTimeWatchpoint):
      (JSC::JSGlobalObject::isHavingABadTime):
      * runtime/JSObject.cpp:
      (JSC::JSObject::visitButterfly):
      (JSC::JSObject::getOwnPropertySlotByIndex):
      (JSC::JSObject::put):
      (JSC::JSObject::putByIndex):
      (JSC::JSObject::enterDictionaryIndexingMode):
      (JSC::JSObject::notifyPresenceOfIndexedAccessors):
      (JSC):
      (JSC::JSObject::createArrayStorage):
      (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
      (JSC::JSObject::switchToSlowPutArrayStorage):
      (JSC::JSObject::setPrototype):
      (JSC::JSObject::resetInheritorID):
      (JSC::JSObject::inheritorID):
      (JSC::JSObject::allowsAccessFrom):
      (JSC::JSObject::deletePropertyByIndex):
      (JSC::JSObject::getOwnPropertyNames):
      (JSC::JSObject::unwrappedGlobalObject):
      (JSC::JSObject::notifyUsedAsPrototype):
      (JSC::JSObject::createInheritorID):
      (JSC::JSObject::defineOwnIndexedProperty):
      (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
      (JSC::JSObject::attemptToInterceptPutByIndexOnHole):
      (JSC::JSObject::putByIndexBeyondVectorLength):
      (JSC::JSObject::putDirectIndexBeyondVectorLength):
      (JSC::JSObject::getNewVectorLength):
      (JSC::JSObject::getOwnPropertyDescriptor):
      * runtime/JSObject.h:
      (JSC::JSObject::mayBeUsedAsPrototype):
      (JSObject):
      (JSC::JSObject::mayInterceptIndexedAccesses):
      (JSC::JSObject::getArrayLength):
      (JSC::JSObject::getVectorLength):
      (JSC::JSObject::canGetIndexQuickly):
      (JSC::JSObject::getIndexQuickly):
      (JSC::JSObject::canSetIndexQuickly):
      (JSC::JSObject::setIndexQuickly):
      (JSC::JSObject::initializeIndex):
      (JSC::JSObject::completeInitialization):
      (JSC::JSObject::inSparseIndexingMode):
      (JSC::JSObject::arrayStorage):
      (JSC::JSObject::arrayStorageOrNull):
      (JSC::JSObject::ensureArrayStorage):
      (JSC):
      (JSC::JSValue::putByIndex):
      * runtime/JSValue.cpp:
      (JSC::JSValue::putToPrimitive):
      (JSC::JSValue::putToPrimitiveByIndex):
      (JSC):
      * runtime/JSValue.h:
      (JSValue):
      * runtime/ObjectPrototype.cpp:
      (JSC::ObjectPrototype::finishCreation):
      * runtime/SparseArrayValueMap.cpp:
      (JSC::SparseArrayValueMap::putEntry):
      (JSC::SparseArrayEntry::put):
      (JSC):
      * runtime/SparseArrayValueMap.h:
      (JSC):
      (SparseArrayEntry):
      * runtime/Structure.cpp:
      (JSC::Structure::anyObjectInChainMayInterceptIndexedAccesses):
      (JSC):
      (JSC::Structure::suggestedIndexingTransition):
      * runtime/Structure.h:
      (Structure):
      (JSC::Structure::mayInterceptIndexedAccesses):
      * runtime/StructureTransitionTable.h:
      (JSC::newIndexingType):
      
      LayoutTests: 
      
      Removed failing expectation for primitive-property-access-edge-cases, and
      added more tests to cover the numerical-setter-on-prototype cases.
      
      * fast/js/array-bad-time-expected.txt: Added.
      * fast/js/array-bad-time.html: Added.
      * fast/js/array-slow-put-expected.txt: Added.
      * fast/js/array-slow-put.html: Added.
      * fast/js/cross-frame-bad-time-expected.txt: Added.
      * fast/js/cross-frame-bad-time.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/object-bad-time-expected.txt: Added.
      * fast/js/object-bad-time.html: Added.
      * fast/js/object-slow-put-expected.txt: Added.
      * fast/js/object-slow-put.html: Added.
      * fast/js/script-tests/array-bad-time.js: Added.
      * fast/js/script-tests/array-slow-put.js: Added.
      (foo):
      * fast/js/script-tests/cross-frame-bad-time.js: Added.
      (foo):
      * fast/js/script-tests/object-bad-time.js: Added.
      (Cons):
      * fast/js/script-tests/object-slow-put.js: Added.
      (Cons):
      (foo):
      * platform/mac/fast/js/primitive-property-access-edge-cases-expected.txt: Removed.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@128802 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1c4a32c9
    • fpizlo@apple.com's avatar
      Array profiling has convergence issues · c7be5be0
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=96891
      
      Reviewed by Gavin Barraclough.
      
      Source/JavaScriptCore: 
      
      Now each array profiling site merges in the indexing type it observed into
      the m_observedArrayModes bitset. The ArrayProfile also uses this to detect
      cases where the structure must have gone polymorphic (if the bitset is
      polymorphic then the structure must be). This achieves something like the
      best of both worlds: on the one hand, we get a probabilistic structure that
      we can use to optimize the monomorphic structure case, but on the other hand,
      we get an accurate view of the set of types that were encountered.
      
      * assembler/MacroAssemblerARMv7.h:
      (JSC::MacroAssemblerARMv7::or32):
      (MacroAssemblerARMv7):
      * assembler/MacroAssemblerX86.h:
      (JSC::MacroAssemblerX86::or32):
      (MacroAssemblerX86):
      * assembler/MacroAssemblerX86_64.h:
      (JSC::MacroAssemblerX86_64::or32):
      (MacroAssemblerX86_64):
      * assembler/X86Assembler.h:
      (X86Assembler):
      (JSC::X86Assembler::orl_rm):
      * bytecode/ArrayProfile.cpp:
      (JSC::ArrayProfile::computeUpdatedPrediction):
      * bytecode/ArrayProfile.h:
      (JSC::ArrayProfile::addressOfArrayModes):
      (JSC::ArrayProfile::structureIsPolymorphic):
      * jit/JIT.h:
      (JIT):
      * jit/JITInlineMethods.h:
      (JSC):
      (JSC::JIT::emitArrayProfilingSite):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      Source/WTF: 
      
      Added functions for testing if something is a power of 2.
      
      * wtf/MathExtras.h:
      (hasZeroOrOneBitsSet):
      (hasTwoOrMoreBitsSet):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@128790 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c7be5be0
  10. 13 Sep, 2012 1 commit
    • fpizlo@apple.com's avatar
      JSC should have property butterflies · d8dd0535
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=91933
      
      Reviewed by Geoffrey Garen.
      
      Source/JavaScriptCore: 
      
      This changes the JSC object model. Previously, all objects had fast lookup for
      named properties. Integer indexed properties were only fast if you used a
      JSArray. With this change, all objects have fast indexed properties. This is
      accomplished without any space overhead by using a bidirectional object layout,
      aka butterflies. Each JSObject has a m_butterfly pointer where previously it
      had a m_outOfLineStorage pointer. To the left of the location pointed to by
      m_butterfly, we place all named out-of-line properties. To the right, we place
      all indexed properties along with indexing meta-data. Though, some indexing
      meta-data is placed in the 8-byte word immediately left of the pointed-to
      location; this is in anticipation of the indexing meta-data being small enough
      in the common case that m_butterfly always points to the first indexed
      property.
              
      This is performance neutral, except on tests that use indexed properties on
      plain objects, where the speed-up is in excess of an order of magnitude.
              
      One notable aspect of what this change brings is that it allows indexing
      storage to morph over time. Currently this is only used to allow all non-array
      objects to start out without any indexed storage. But it could be used for
      some kinds of array type inference in the future.
      
      * API/JSCallbackObject.h:
      (JSCallbackObject):
      * API/JSCallbackObjectFunctions.h:
      (JSC::::getOwnPropertySlotByIndex):
      (JSC):
      (JSC::::getOwnNonIndexPropertyNames):
      * API/JSObjectRef.cpp:
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/ArrayProfile.h:
      (JSC):
      (JSC::arrayModeFromStructure):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::emitDirectPutById):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGAdjacencyList.h:
      (JSC::DFG::AdjacencyList::AdjacencyList):
      (AdjacencyList):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::fromObserved):
      (JSC::DFG::modeAlreadyChecked):
      (JSC::DFG::modeToString):
      * dfg/DFGArrayMode.h:
      (DFG):
      (JSC::DFG::modeUsesButterfly):
      (JSC::DFG::modeIsJSArray):
      (JSC::DFG::isInBoundsAccess):
      (JSC::DFG::modeSupportsLength):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::handleGetByOffset):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::addNode):
      (FixupPhase):
      (JSC::DFG::FixupPhase::checkArray):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::byValIsPure):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::Node):
      (Node):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOperations.cpp:
      (JSC::DFG::putByVal):
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::generateProtoChainAccessStub):
      (JSC::DFG::tryCacheGetByID):
      (JSC::DFG::tryBuildGetByIDList):
      (JSC::DFG::emitPutReplaceStub):
      (JSC::DFG::emitPutTransitionStub):
      (JSC::DFG::tryBuildPutByIdList):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::checkArray):
      (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
      (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
      (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
      (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::cachedGetById):
      (JSC::DFG::SpeculativeJIT::cachedPutById):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::cachedGetById):
      (JSC::DFG::SpeculativeJIT::cachedPutById):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGStructureCheckHoistingPhase.cpp:
      (JSC::DFG::StructureCheckHoistingPhase::run):
      * heap/CopiedSpace.h:
      (CopiedSpace):
      * jit/JIT.h:
      * jit/JITInlineMethods.h:
      (JSC::JIT::emitAllocateBasicJSObject):
      (JSC::JIT::emitAllocateBasicStorage):
      (JSC::JIT::emitAllocateJSArray):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_new_array):
      (JSC::JIT::emitSlow_op_new_array):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::compileGetDirectOffset):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::compileGetByIdHotPath):
      (JSC::JIT::emit_op_put_by_id):
      (JSC::JIT::compilePutDirectOffset):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::compileGetByIdHotPath):
      (JSC::JIT::emit_op_put_by_id):
      (JSC::JIT::compilePutDirectOffset):
      (JSC::JIT::compileGetDirectOffset):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * jsc.cpp:
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      * runtime/Arguments.cpp:
      (JSC::Arguments::deletePropertyByIndex):
      (JSC::Arguments::defineOwnProperty):
      * runtime/ArrayConstructor.cpp:
      * runtime/ArrayConventions.h: Added.
      (JSC):
      (JSC::isDenseEnoughForVector):
      (JSC::indexingHeaderForArray):
      (JSC::baseIndexingHeaderForArray):
      * runtime/ArrayPrototype.cpp:
      (JSC::ArrayPrototype::create):
      (JSC):
      (JSC::ArrayPrototype::ArrayPrototype):
      (JSC::arrayProtoFuncToString):
      (JSC::arrayProtoFuncJoin):
      (JSC::arrayProtoFuncSort):
      (JSC::arrayProtoFuncFilter):
      (JSC::arrayProtoFuncMap):
      (JSC::arrayProtoFuncEvery):
      (JSC::arrayProtoFuncForEach):
      (JSC::arrayProtoFuncSome):
      (JSC::arrayProtoFuncReduce):
      (JSC::arrayProtoFuncReduceRight):
      * runtime/ArrayPrototype.h:
      (ArrayPrototype):
      (JSC::ArrayPrototype::createStructure):
      * runtime/ArrayStorage.h: Added.
      (JSC):
      (ArrayStorage):
      (JSC::ArrayStorage::ArrayStorage):
      (JSC::ArrayStorage::from):
      (JSC::ArrayStorage::butterfly):
      (JSC::ArrayStorage::indexingHeader):
      (JSC::ArrayStorage::length):
      (JSC::ArrayStorage::setLength):
      (JSC::ArrayStorage::vectorLength):
      (JSC::ArrayStorage::setVectorLength):
      (JSC::ArrayStorage::copyHeaderFromDuringGC):
      (JSC::ArrayStorage::inSparseMode):
      (JSC::ArrayStorage::lengthOffset):
      (JSC::ArrayStorage::vectorLengthOffset):
      (JSC::ArrayStorage::numValuesInVectorOffset):
      (JSC::ArrayStorage::vectorOffset):
      (JSC::ArrayStorage::indexBiasOffset):
      (JSC::ArrayStorage::sparseMapOffset):
      (JSC::ArrayStorage::sizeFor):
      * runtime/Butterfly.h: Added.
      (JSC):
      (Butterfly):
      (JSC::Butterfly::Butterfly):
      (JSC::Butterfly::totalSize):
      (JSC::Butterfly::fromBase):
      (JSC::Butterfly::offsetOfIndexingHeader):
      (JSC::Butterfly::offsetOfPublicLength):
      (JSC::Butterfly::offsetOfVectorLength):
      (JSC::Butterfly::indexingHeader):
      (JSC::Butterfly::propertyStorage):
      (JSC::Butterfly::indexingPayload):
      (JSC::Butterfly::arrayStorage):
      (JSC::Butterfly::offsetOfPropertyStorage):
      (JSC::Butterfly::indexOfPropertyStorage):
      (JSC::Butterfly::base):
      * runtime/ButterflyInlineMethods.h: Added.
      (JSC):
      (JSC::Butterfly::createUninitialized):
      (JSC::Butterfly::create):
      (JSC::Butterfly::createUninitializedDuringCollection):
      (JSC::Butterfly::base):
      (JSC::Butterfly::growPropertyStorage):
      (JSC::Butterfly::growArrayRight):
      (JSC::Butterfly::resizeArray):
      (JSC::Butterfly::unshift):
      (JSC::Butterfly::shift):
      * runtime/ClassInfo.h:
      (MethodTable):
      (JSC):
      * runtime/IndexingHeader.h: Added.
      (JSC):
      (IndexingHeader):
      (JSC::IndexingHeader::offsetOfIndexingHeader):
      (JSC::IndexingHeader::offsetOfPublicLength):
      (JSC::IndexingHeader::offsetOfVectorLength):
      (JSC::IndexingHeader::IndexingHeader):
      (JSC::IndexingHeader::vectorLength):
      (JSC::IndexingHeader::setVectorLength):
      (JSC::IndexingHeader::publicLength):
      (JSC::IndexingHeader::setPublicLength):
      (JSC::IndexingHeader::from):
      (JSC::IndexingHeader::fromEndOf):
      (JSC::IndexingHeader::propertyStorage):
      (JSC::IndexingHeader::arrayStorage):
      (JSC::IndexingHeader::butterfly):
      * runtime/IndexingHeaderInlineMethods.h: Added.
      (JSC):
      (JSC::IndexingHeader::preCapacity):
      (JSC::IndexingHeader::indexingPayloadSizeInBytes):
      * runtime/IndexingType.h: Added.
      (JSC):
      (JSC::hasIndexingHeader):
      * runtime/JSActivation.cpp:
      (JSC::JSActivation::JSActivation):
      (JSC::JSActivation::visitChildren):
      (JSC::JSActivation::getOwnNonIndexPropertyNames):
      * runtime/JSActivation.h:
      (JSActivation):
      (JSC::JSActivation::tearOff):
      * runtime/JSArray.cpp:
      (JSC):
      (JSC::createArrayButterflyInDictionaryIndexingMode):
      (JSC::JSArray::setLengthWritable):
      (JSC::JSArray::defineOwnProperty):
      (JSC::JSArray::getOwnPropertySlot):
      (JSC::JSArray::getOwnPropertyDescriptor):
      (JSC::JSArray::put):
      (JSC::JSArray::deleteProperty):
      (JSC::JSArray::getOwnNonIndexPropertyNames):
      (JSC::JSArray::unshiftCountSlowCase):
      (JSC::JSArray::setLength):
      (JSC::JSArray::pop):
      (JSC::JSArray::push):
      (JSC::JSArray::shiftCount):
      (JSC::JSArray::unshiftCount):
      (JSC::JSArray::sortNumeric):
      (JSC::JSArray::sort):
      (JSC::JSArray::fillArgList):
      (JSC::JSArray::copyToArguments):
      (JSC::JSArray::compactForSorting):
      * runtime/JSArray.h:
      (JSC):
      (JSArray):
      (JSC::JSArray::JSArray):
      (JSC::JSArray::length):
      (JSC::JSArray::createStructure):
      (JSC::JSArray::isLengthWritable):
      (JSC::createArrayButterfly):
      (JSC::JSArray::create):
      (JSC::JSArray::tryCreateUninitialized):
      * runtime/JSBoundFunction.cpp:
      (JSC::boundFunctionCall):
      (JSC::boundFunctionConstruct):
      (JSC::JSBoundFunction::finishCreation):
      * runtime/JSCell.cpp:
      (JSC::JSCell::getOwnNonIndexPropertyNames):
      (JSC):
      * runtime/JSCell.h:
      (JSCell):
      * runtime/JSFunction.cpp:
      (JSC::JSFunction::getOwnPropertySlot):
      (JSC::JSFunction::getOwnPropertyDescriptor):
      (JSC::JSFunction::getOwnNonIndexPropertyNames):
      (JSC::JSFunction::defineOwnProperty):
      * runtime/JSFunction.h:
      (JSFunction):
      * runtime/JSGlobalData.cpp:
      (JSC::JSGlobalData::JSGlobalData):
      * runtime/JSGlobalData.h:
      (JSGlobalData):
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::reset):
      * runtime/JSONObject.cpp:
      (JSC::Stringifier::Holder::appendNextProperty):
      (JSC::Walker::walk):
      * runtime/JSObject.cpp:
      (JSC):
      (JSC::JSObject::visitButterfly):
      (JSC::JSObject::visitChildren):
      (JSC::JSFinalObject::visitChildren):
      (JSC::JSObject::getOwnPropertySlotByIndex):
      (JSC::JSObject::put):
      (JSC::JSObject::putByIndex):
      (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
      (JSC::JSObject::enterDictionaryIndexingMode):
      (JSC::JSObject::createArrayStorage):
      (JSC::JSObject::createInitialArrayStorage):
      (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
      (JSC::JSObject::putDirectAccessor):
      (JSC::JSObject::deleteProperty):
      (JSC::JSObject::deletePropertyByIndex):
      (JSC::JSObject::getOwnPropertyNames):
      (JSC::JSObject::getOwnNonIndexPropertyNames):
      (JSC::JSObject::preventExtensions):
      (JSC::JSObject::fillGetterPropertySlot):
      (JSC::JSObject::putIndexedDescriptor):
      (JSC::JSObject::defineOwnIndexedProperty):
      (JSC::JSObject::allocateSparseIndexMap):
      (JSC::JSObject::deallocateSparseIndexMap):
      (JSC::JSObject::putByIndexBeyondVectorLengthWithArrayStorage):
      (JSC::JSObject::putByIndexBeyondVectorLength):
      (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage):
      (JSC::JSObject::putDirectIndexBeyondVectorLength):
      (JSC::JSObject::getNewVectorLength):
      (JSC::JSObject::increaseVectorLength):
      (JSC::JSObject::checkIndexingConsistency):
      (JSC::JSObject::growOutOfLineStorage):
      (JSC::JSObject::getOwnPropertyDescriptor):
      (JSC::putDescriptor):
      (JSC::JSObject::putDirectMayBeIndex):
      (JSC::JSObject::defineOwnNonIndexProperty):
      (JSC::JSObject::defineOwnProperty):
      (JSC::JSObject::getOwnPropertySlotSlow):
      * runtime/JSObject.h:
      (JSC::JSObject::getArrayLength):
      (JSObject):
      (JSC::JSObject::getVectorLength):
      (JSC::JSObject::putDirectIndex):
      (JSC::JSObject::canGetIndexQuickly):
      (JSC::JSObject::getIndexQuickly):
      (JSC::JSObject::canSetIndexQuickly):
      (JSC::JSObject::setIndexQuickly):
      (JSC::JSObject::initializeIndex):
      (JSC::JSObject::completeInitialization):
      (JSC::JSObject::inSparseIndexingMode):
      (JSC::JSObject::butterfly):
      (JSC::JSObject::outOfLineStorage):
      (JSC::JSObject::offsetForLocation):
      (JSC::JSObject::indexingShouldBeSparse):
      (JSC::JSObject::butterflyOffset):
      (JSC::JSObject::butterflyAddress):
      (JSC::JSObject::arrayStorage):
      (JSC::JSObject::arrayStorageOrZero):
      (JSC::JSObject::ensureArrayStorage):
      (JSC::JSObject::checkIndexingConsistency):
      (JSC::JSNonFinalObject::JSNonFinalObject):
      (JSC):
      (JSC::JSObject::setButterfly):
      (JSC::JSObject::setButterflyWithoutChangingStructure):
      (JSC::JSObject::JSObject):
      (JSC::JSObject::inlineGetOwnPropertySlot):
      (JSC::JSObject::putDirectInternal):
      (JSC::JSObject::setStructureAndReallocateStorageIfNecessary):
      (JSC::JSObject::putDirectWithoutTransition):
      (JSC::offsetInButterfly):
      (JSC::offsetRelativeToPatchedStorage):
      (JSC::indexRelativeToBase):
      (JSC::offsetRelativeToBase):
      * runtime/JSPropertyNameIterator.cpp:
      (JSC::JSPropertyNameIterator::create):
      * runtime/JSSymbolTableObject.cpp:
      (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):
      * runtime/JSSymbolTableObject.h:
      (JSSymbolTableObject):
      * runtime/JSTypeInfo.h:
      (JSC):
      (JSC::TypeInfo::interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero):
      (JSC::TypeInfo::overridesGetPropertyNames):
      * runtime/LiteralParser.cpp:
      (JSC::::parse):
      * runtime/ObjectConstructor.cpp:
      * runtime/ObjectPrototype.cpp:
      (JSC::ObjectPrototype::ObjectPrototype):
      (JSC):
      * runtime/ObjectPrototype.h:
      (ObjectPrototype):
      * runtime/PropertyOffset.h:
      (JSC::offsetInOutOfLineStorage):
      * runtime/PropertyStorage.h: Added.
      (JSC):
      * runtime/PutDirectIndexMode.h: Added.
      (JSC):
      * runtime/RegExpMatchesArray.cpp:
      (JSC::RegExpMatchesArray::RegExpMatchesArray):
      (JSC):
      (JSC::RegExpMatchesArray::create):
      (JSC::RegExpMatchesArray::finishCreation):
      * runtime/RegExpMatchesArray.h:
      (RegExpMatchesArray):
      (JSC::RegExpMatchesArray::createStructure):
      * runtime/RegExpObject.cpp:
      (JSC::RegExpObject::getOwnNonIndexPropertyNames):
      * runtime/RegExpObject.h:
      (RegExpObject):
      * runtime/Reject.h: Added.
      (JSC):
      (JSC::reject):
      * runtime/SparseArrayValueMap.cpp: Added.
      (JSC):
      * runtime/SparseArrayValueMap.h: Added.
      (JSC):
      (SparseArrayEntry):
      (JSC::SparseArrayEntry::SparseArrayEntry):
      (SparseArrayValueMap):
      (JSC::SparseArrayValueMap::sparseMode):
      (JSC::SparseArrayValueMap::setSparseMode):
      (JSC::SparseArrayValueMap::lengthIsReadOnly):
      (JSC::SparseArrayValueMap::setLengthIsReadOnly):
      (JSC::SparseArrayValueMap::find):
      (JSC::SparseArrayValueMap::remove):
      (JSC::SparseArrayValueMap::notFound):
      (JSC::SparseArrayValueMap::isEmpty):
      (JSC::SparseArrayValueMap::contains):
      (JSC::SparseArrayValueMap::size):
      (JSC::SparseArrayValueMap::begin):
      (JSC::SparseArrayValueMap::end):
      * runtime/SparseArrayValueMapInlineMethods.h: Added.
      (JSC):
      (JSC::SparseArrayValueMap::SparseArrayValueMap):
      (JSC::SparseArrayValueMap::~SparseArrayValueMap):
      (JSC::SparseArrayValueMap::finishCreation):
      (JSC::SparseArrayValueMap::create):
      (JSC::SparseArrayValueMap::destroy):
      (JSC::SparseArrayValueMap::createStructure):
      (JSC::SparseArrayValueMap::add):
      (JSC::SparseArrayValueMap::putEntry):
      (JSC::SparseArrayValueMap::putDirect):
      (JSC::SparseArrayEntry::get):
      (JSC::SparseArrayEntry::getNonSparseMode):
      (JSC::SparseArrayValueMap::visitChildren):
      * runtime/StorageBarrier.h: Removed.
      * runtime/StringObject.cpp:
      (JSC::StringObject::putByIndex):
      (JSC):
      (JSC::StringObject::deletePropertyByIndex):
      * runtime/StringObject.h:
      (StringObject):
      * runtime/StringPrototype.cpp:
      * runtime/Structure.cpp:
      (JSC::Structure::Structure):
      (JSC::Structure::materializePropertyMap):
      (JSC::Structure::nonPropertyTransition):
      (JSC):
      * runtime/Structure.h:
      (Structure):
      (JSC::Structure::indexingType):
      (JSC::Structure::indexingTypeIncludingHistory):
      (JSC::Structure::indexingTypeOffset):
      (JSC::Structure::create):
      * runtime/StructureTransitionTable.h:
      (JSC):
      (JSC::toAttributes):
      (JSC::newIndexingType):
      (JSC::StructureTransitionTable::Hash::hash):
      * tests/mozilla/js1_6/Array/regress-304828.js:
      
      Source/WebCore: 
      
      Teach the DOM that to intercept get/put on indexed properties, you now have
      to override getOwnPropertySlotByIndex and putByIndex.
      
      No new tests because no new behavior. One test was rebased because indexed
      property iteration order now matches other engines (indexed properties always
      come first).
      
      * bindings/js/ArrayValue.cpp:
      (WebCore::ArrayValue::get):
      * bindings/js/JSBlobCustom.cpp:
      (WebCore::JSBlobConstructor::constructJSBlob):
      * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
      (WebCore::JSCanvasRenderingContext2D::setWebkitLineDash):
      * bindings/js/JSDOMStringListCustom.cpp:
      (WebCore::toDOMStringList):
      * bindings/js/JSDOMStringMapCustom.cpp:
      (WebCore::JSDOMStringMap::deletePropertyByIndex):
      (WebCore):
      * bindings/js/JSDOMWindowCustom.cpp:
      (WebCore::JSDOMWindow::getOwnPropertySlot):
      (WebCore::JSDOMWindow::getOwnPropertySlotByIndex):
      (WebCore):
      (WebCore::JSDOMWindow::putByIndex):
      (WebCore::JSDOMWindow::deletePropertyByIndex):
      * bindings/js/JSDOMWindowShell.cpp:
      (WebCore::JSDOMWindowShell::getOwnPropertySlotByIndex):
      (WebCore):
      (WebCore::JSDOMWindowShell::putByIndex):
      (WebCore::JSDOMWindowShell::deletePropertyByIndex):
      * bindings/js/JSDOMWindowShell.h:
      (JSDOMWindowShell):
      * bindings/js/JSHistoryCustom.cpp:
      (WebCore::JSHistory::deletePropertyByIndex):
      (WebCore):
      * bindings/js/JSInspectorFrontendHostCustom.cpp:
      (WebCore::populateContextMenuItems):
      * bindings/js/JSLocationCustom.cpp:
      (WebCore::JSLocation::deletePropertyByIndex):
      (WebCore):
      * bindings/js/JSStorageCustom.cpp:
      (WebCore::JSStorage::deletePropertyByIndex):
      (WebCore):
      * bindings/js/JSWebSocketCustom.cpp:
      (WebCore::JSWebSocketConstructor::constructJSWebSocket):
      * bindings/js/ScriptValue.cpp:
      (WebCore::jsToInspectorValue):
      * bindings/js/SerializedScriptValue.cpp:
      (WebCore::CloneSerializer::serialize):
      * bindings/scripts/CodeGeneratorJS.pm:
      (GenerateHeader):
      (GenerateImplementation):
      * bridge/runtime_array.cpp:
      (JSC::RuntimeArray::RuntimeArray):
      * bridge/runtime_array.h:
      (JSC::RuntimeArray::createStructure):
      (RuntimeArray):
      
      LayoutTests: 
      
      Modify the JSON test to indicate that iterating over properties now returns
      indexed properties first. This is a behavior change that makes us more
      compliant with other implementations.
              
      Also check in new expected file for the edge cases of indexed property access
      with prototype accessors. This changeset introduces a known regression in that
      department, which is tracked here: https://bugs.webkit.org/show_bug.cgi?id=96596
      
      * fast/js/resources/JSON-stringify.js:
      * platform/mac/fast/js/primitive-property-access-edge-cases-expected.txt: Added.
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@128400 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d8dd0535
  11. 15 Aug, 2012 1 commit
    • fpizlo@apple.com's avatar
      Array checks should use the structure, not the class info · f24804c6
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=93150
      
      Reviewed by Mark Hahnenberg.
      
      This changes all array checks used in array accesses (get, put, get length,
      push, pop) to use the structure, not the class info. Additionally, these
      checks in the LLInt and baseline JIT record the structure in an ArrayProfile,
      so that the DFG can know exactly what structure to check for.
              
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * bytecode/ArrayProfile.cpp: Added.
      (JSC):
      (JSC::ArrayProfile::computeUpdatedPrediction):
      * bytecode/ArrayProfile.h: Added.
      (JSC):
      (JSC::arrayModeFromStructure):
      (ArrayProfile):
      (JSC::ArrayProfile::ArrayProfile):
      (JSC::ArrayProfile::bytecodeOffset):
      (JSC::ArrayProfile::addressOfLastSeenStructure):
      (JSC::ArrayProfile::observeStructure):
      (JSC::ArrayProfile::expectedStructure):
      (JSC::ArrayProfile::structureIsPolymorphic):
      (JSC::ArrayProfile::hasDefiniteStructure):
      (JSC::ArrayProfile::observedArrayModes):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dump):
      (JSC::CodeBlock::getArrayProfile):
      (JSC):
      (JSC::CodeBlock::getOrAddArrayProfile):
      (JSC::CodeBlock::updateAllPredictionsAndCountLiveness):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::executionEntryCount):
      (JSC::CodeBlock::numberOfArrayProfiles):
      (JSC::CodeBlock::arrayProfiles):
      (JSC::CodeBlock::addArrayProfile):
      (CodeBlock):
      * bytecode/Instruction.h:
      (JSC):
      (JSC::Instruction::Instruction):
      * bytecode/Opcode.h:
      (JSC):
      (JSC::padOpcodeName):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::emitGetArgumentByVal):
      (JSC::BytecodeGenerator::emitGetByVal):
      (JSC::BytecodeGenerator::emitPutByVal):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::execute):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::StructureAbstractValue::hasSingleton):
      (StructureAbstractValue):
      (JSC::DFG::StructureAbstractValue::singleton):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::speculateArray):
      (DFG):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
      (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGStructureCheckHoistingPhase.cpp:
      (JSC::DFG::StructureCheckHoistingPhase::run):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emit_op_get_by_val):
      (JSC::JIT::emit_op_put_by_val):
      (JSC::JIT::privateCompilePatchGetArrayLength):
      * llint/LLIntOffsetsExtractor.cpp:
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      * runtime/Structure.h:
      (Structure):
      (JSC::Structure::classInfoOffset):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@125637 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f24804c6