1. 24 Jul, 2013 40 commits
    • oliver@apple.com's avatar
      fourthTier: DFG should support op_in and it should use patching to make it fast · b3e5acbf
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117385
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Implement op_in in the DFG and give it patching. The code we generate is just
      a jump on the hot path, and the slow paths generate stubs and link the jump to
      them. I didn't want to bother with patching structures and load offsets and
      the like, although I probably could have.
      
      This is a ginormous speed-up on microbenchmarks for "in", obviously.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpAssumingJITType):
      (JSC::CodeBlock::resetStubInternal):
      (JSC::structureStubInfoLessThan):
      (JSC):
      (JSC::CodeBlock::sortStructureStubInfos):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * bytecode/StructureStubInfo.cpp:
      (JSC::StructureStubInfo::deref):
      (JSC::StructureStubInfo::visitWeakReferences):
      * bytecode/StructureStubInfo.h:
      (JSC::isInAccess):
      (JSC):
      (StructureStubInfo):
      (JSC::StructureStubInfo::initInList):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCCallHelpers.h:
      (JSC::DFG::CCallHelpers::setupResults):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGPRInfo.h:
      (JSC::DFG::JSValueRegs::payloadOnly):
      (JSValueRegs):
      (JSC::DFG::JSValueRegs::JSValueRegs):
      (JSC::DFG::JSValueRegs::operator!):
      (JSC::DFG::JSValueSource::operator!):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::InRecord::InRecord):
      (InRecord):
      (DFG):
      (JITCompiler):
      (JSC::DFG::JITCompiler::addIn):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::tryRepatchIn):
      (DFG):
      (JSC::DFG::dfgRepatchIn):
      (JSC::DFG::dfgResetIn):
      * dfg/DFGRepatch.h:
      (DFG):
      (JSC::DFG::dfgResetIn):
      * dfg/DFGSlowPathGenerator.h:
      (JSC::DFG::CallSlowPathGenerator::CallSlowPathGenerator):
      (JSC::DFG::CallSlowPathGenerator::tearDown):
      (JSC::DFG::CallResultAndNoArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndOneArgumentSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndTwoArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndThreeArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndFourArgumentsSlowPathGenerator::generateInternal):
      (JSC::DFG::CallResultAndFiveArgumentsSlowPathGenerator::generateInternal):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileIn):
      (DFG):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::extractResult):
      (DFG):
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::callOperation):
      (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheckSetResult):
      (JSC::DFG::SpeculativeJIT::appendCallSetResult):
      (JSC::DFG::JSValueOperand::tagGPR):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * runtime/JSCJSValue.cpp:
      (JSC::JSValue::dump):
      * runtime/JSString.h:
      (JSString):
      (JSC::JSString::tryGetValueImpl):
      (JSC):
      * runtime/Operations.h:
      (JSC::normalizePrototypeChainForChainAccess):
      
      Source/WTF:
      
      Reviewed by Geoffrey Garen.
      
      Now if you pass a null StringImpl* then something will still get printed instead
      of crashing. I figure that this is broadly useful for debug code, and I make use
      of it in the JSC portion of this patch.
      
      * wtf/PrintStream.cpp:
      (WTF::printInternal):
      
      LayoutTests:
      
      Reviewed by Geoffrey Garen.
      
      Test coverage for op_in performance.
      
      * fast/js/regress/in-four-cases-expected.txt: Added.
      * fast/js/regress/in-four-cases.html: Added.
      * fast/js/regress/in-one-case-false-expected.txt: Added.
      * fast/js/regress/in-one-case-false.html: Added.
      * fast/js/regress/in-one-case-true-expected.txt: Added.
      * fast/js/regress/in-one-case-true.html: Added.
      * fast/js/regress/in-two-cases-expected.txt: Added.
      * fast/js/regress/in-two-cases.html: Added.
      * fast/js/regress/script-tests/in-four-cases.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/in-one-case-false.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/in-one-case-true.js: Added.
      (foo):
      (bar):
      * fast/js/regress/script-tests/in-two-cases.js: Added.
      (foo):
      (bar):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153225 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      b3e5acbf
    • oliver@apple.com's avatar
      fourthTier: A few fixups to standalone-pre.js · 336e13ce
      oliver@apple.com authored
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153224 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      336e13ce
    • oliver@apple.com's avatar
      fourthTier: The Math object should not be polymorphic · 524161ed
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117576
      
      Reviewed by Oliver Hunt.
      
      Fill in the Math object eagerly, to avoid its structure changing during
      execution. There are lots of ways to skin this cat; this one seemed
      easiest, and justified given the relative hotness of math operations.
      
      20% speedup on DSP-filtrr tests, small speedups on a few Kraken tests.
      
      * DerivedSources.make:
      * JavaScriptCore.order:
      * create_hash_table:
      * interpreter/CallFrame.h:
      (JSC::ExecState::jsonTable): Removed the Math object's static table.
      
      * runtime/JSObject.cpp:
      (JSC::JSObject::putDirectNativeFunctionWithoutTransition):
      * runtime/JSObject.h:
      * runtime/MathObject.cpp:
      (JSC::MathObject::finishCreation):
      * runtime/MathObject.h:
      (JSC::MathObject::create): Set up the Math object at construction time.
      
      * runtime/VM.cpp:
      (JSC::VM::VM):
      (JSC::VM::~VM):
      * runtime/VM.h: Removed the Math object's static table.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153223 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      524161ed
    • oliver@apple.com's avatar
      fourthTier: The baseline jit and LLint should use common slow paths · 7ca71435
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116889
      
      Reviewed by Filip Pizlo.
      
      Moved the llint_slow_paths that return JSValue along with several others to CommonSlowPaths.cpp.
      Eliminated the related JIT stubs.  Changes the baseline JIT to call these new common stubs.
      Added a simple slow path call class that uses argument registers or the stack instead of
      JITStackFrame.  Changes the exception mechanism for to check for an exception after making
      a slowpath call instead of returning to the handler directly form the slowpath function.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * jit/JIT.cpp:
      (JSC::JIT::privateCompileMainPass):
      * jit/JIT.h:
      (JIT):
      * jit/JITArithmetic.cpp:
      (JSC::JIT::emitSlow_op_negate):
      (JSC::JIT::emitSlow_op_lshift):
      (JSC::JIT::emitSlow_op_rshift):
      (JSC::JIT::emitSlow_op_urshift):
      (JSC::JIT::emitSlow_op_bitand):
      (JSC::JIT::emitSlow_op_inc):
      (JSC::JIT::emitSlow_op_dec):
      (JSC::JIT::emitSlow_op_mod):
      (JSC::JIT::emit_op_mod):
      (JSC::JIT::compileBinaryArithOpSlowCase):
      (JSC::JIT::emit_op_add):
      (JSC::JIT::emitSlow_op_add):
      (JSC::JIT::emitSlow_op_mul):
      (JSC::JIT::emitSlow_op_div):
      (JSC::JIT::emitSlow_op_sub):
      * jit/JITArithmetic32_64.cpp:
      (JSC::JIT::emitSlow_op_negate):
      (JSC::JIT::emitSlow_op_lshift):
      (JSC::JIT::emitRightShiftSlowCase):
      (JSC::JIT::emitSlow_op_bitand):
      (JSC::JIT::emitSlow_op_bitor):
      (JSC::JIT::emitSlow_op_bitxor):
      (JSC::JIT::emitSlow_op_inc):
      (JSC::JIT::emitSlow_op_dec):
      (JSC::JIT::emit_op_add):
      (JSC::JIT::emitSlow_op_add):
      (JSC::JIT::emitSlow_op_sub):
      (JSC::JIT::emitSlow_op_mul):
      (JSC::JIT::emitSlow_op_div):
      (JSC::JIT::emit_op_mod):
      (JSC::JIT::emitSlow_op_mod):
      * jit/JITExceptions.cpp:
      (JSC::getExceptionLocation):
      (JSC::genericThrow):
      (JSC::jitThrowNew):
      * jit/JITExceptions.h:
      (ExceptionHandler):
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emit_op_strcat):
      (JSC::JIT::emitSlow_op_create_this):
      (JSC::JIT::emitSlow_op_to_this):
      (JSC::JIT::emitSlow_op_to_primitive):
      (JSC::JIT::emitSlow_op_not):
      (JSC::JIT::emitSlow_op_bitxor):
      (JSC::JIT::emitSlow_op_bitor):
      (JSC::JIT::emitSlow_op_stricteq):
      (JSC::JIT::emitSlow_op_nstricteq):
      (JSC::JIT::emitSlow_op_to_number):
      * jit/JITOpcodes32_64.cpp:
      (JSC::JIT::privateCompileCTINativeCall):
      (JSC::JIT::emitSlow_op_to_primitive):
      (JSC::JIT::emit_op_strcat):
      (JSC::JIT::emitSlow_op_not):
      (JSC::JIT::emitSlow_op_stricteq):
      (JSC::JIT::emitSlow_op_nstricteq):
      (JSC::JIT::emitSlow_op_to_number):
      (JSC::JIT::emit_op_create_arguments):
      (JSC::JIT::emitSlow_op_create_this):
      (JSC::JIT::emitSlow_op_to_this):
      (JSC::JIT::emitSlow_op_get_argument_by_val):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      (JSC::cti_vm_throw_slowpath):
      * jit/JITStubs.h:
      * jit/JITStubsARM.h:
      * jit/JITStubsARMv7.h:
      * jit/JITStubsMIPS.h:
      * jit/JITStubsSH4.h:
      * jit/JITStubsX86.h:
      * jit/JITStubsX86_64.h:
      * jit/JSInterfaceJIT.h:
      (JSInterfaceJIT):
      * jit/SlowPathCall.h: Added.
      (JITSlowPathCall):
      (JSC::JITSlowPathCall::JITSlowPathCall):
      (JSC::JITSlowPathCall::call):
      * jit/ThunkGenerators.cpp:
      (JSC::nativeForGenerator):
      * llint/LLIntSlowPaths.cpp:
      (LLInt):
      * llint/LLIntSlowPaths.h:
      (LLInt):
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter.cpp:
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      * runtime/CommonSlowPaths.cpp: Added.
      (JSC::SLOW_PATH_DECL):
      * runtime/CommonSlowPaths.h:
      (SlowPathReturnType):
      (JSC::encodeResult):
      (JSC::decodeResult):
      * runtime/JSCJSValue.h:
      (JSValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153222 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7ca71435
    • oliver@apple.com's avatar
      fourthTier: Re-worked non-local variable resolution · 58c86752
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117375
      
      Reviewed by Filip Pizlo.
      
      Source/JavaScriptCore:
      
      This patch has two goals:
      
      (1) Simplicity.
      
          * Net removes 15 opcodes.
          * Net removes 2,000 lines of code.
          * Removes setPair() from the DFG: All DFG nodes have 1 result register now.
      
      (2) Performance.
      
          * 2%-3% speedup on SunSpider (20% in LLInt and Baseline JIT)
          * 2% speedup on v8-spider
          * 10% speedup on js-regress-hashmap*
          * Amusing 2X speedup on js-regress-poly-stricteq
      
      The bytecode now separates the scope chain resolution opcode from the
      scope access opcode.
      
          OLD:
              get_scoped_var  r0, 1, 0
              inc             r0
              put_scoped_var  1, 0, r0
      
          NEW:
              resolve_scope   r0, x(@id0)
              get_from_scope  r1, r0, x(@id0)
              inc             r1
              put_to_scope    r0, x(@id0), r1
      
      Also, we link non-local variable resolution opcodes at CodeBlock link
      time instead of time of first opcode execution.
      
      This means that we can represent all possible non-local variable
      resolutions using just three opcodes, and any optimizations in these
      opcodes naturally apply across-the-board.
      
      * API/JSCTestRunnerUtils.cpp:
      (JSC::numberOfDFGCompiles):
      * GNUmakefile.list.am:
      * JavaScriptCore.gypi:
      * JavaScriptCore.order:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri: Build!
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpBytecode): Updated for removed things.
      
      (JSC::CodeBlock::CodeBlock): Always provide the full scope chain when
      creating a CodeBlock, so we can perform non-local variable resolution.
      
      Added code to perform linking for these opcodes. This is where we figure
      out which non-local variable resolutions are optimizable, and how.
      
      (JSC::CodeBlock::finalizeUnconditionally):
      (JSC::CodeBlock::noticeIncomingCall):
      (JSC::CodeBlock::optimizeAfterWarmUp):
      (JSC::CodeBlock::optimizeAfterLongWarmUp):
      (JSC::CodeBlock::optimizeSoon): Updated for removed things.
      
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::needsActivation):
      (JSC::GlobalCodeBlock::GlobalCodeBlock):
      (JSC::ProgramCodeBlock::ProgramCodeBlock):
      (JSC::EvalCodeBlock::EvalCodeBlock):
      (JSC::FunctionCodeBlock::FunctionCodeBlock):
      * bytecode/EvalCodeCache.h:
      (JSC::EvalCodeCache::getSlow): Updated for interface changes.
      
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor): Treat global object access as
      optimizable even though the global object has a custom property access
      callback. This is what we've always done since, otherwise, we can't
      optimize globals. (In future, we probably want to figure out a more
      targeted policy than "any property access callback means no
      optimization".)
      
      * bytecode/GlobalResolveInfo.h: Removed.
      * bytecode/Instruction.h:
      * bytecode/Opcode.h:
      (JSC::padOpcodeName):
      
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor): Like GetByIdStatus.
      
      * bytecode/ResolveGlobalStatus.cpp: Removed.
      * bytecode/ResolveGlobalStatus.h: Removed.
      * bytecode/ResolveOperation.h: Removed.
      
      * bytecode/UnlinkedCodeBlock.cpp:
      (JSC::generateFunctionCodeBlock):
      (JSC::UnlinkedFunctionExecutable::codeBlockFor):
      (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
      * bytecode/UnlinkedCodeBlock.h: Don't provide a scope chain to unlinked
      code blocks. Giving a scope to an unscoped compilation unit invites
      programming errors.
      
      * bytecode/Watchpoint.h:
      (JSC::WatchpointSet::addressOfIsInvalidated):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::BytecodeGenerator):
      (JSC::BytecodeGenerator::resolveCallee):
      (JSC::BytecodeGenerator::local):
      (JSC::BytecodeGenerator::constLocal):
      (JSC::BytecodeGenerator::resolveType):
      (JSC::BytecodeGenerator::emitResolveScope):
      (JSC::BytecodeGenerator::emitGetFromScope):
      (JSC::BytecodeGenerator::emitPutToScope):
      (JSC::BytecodeGenerator::emitInstanceOf):
      (JSC::BytecodeGenerator::emitPushWithScope):
      (JSC::BytecodeGenerator::emitPopScope):
      (JSC::BytecodeGenerator::pushFinallyContext):
      (JSC::BytecodeGenerator::emitComplexPopScopes):
      (JSC::BytecodeGenerator::popTryAndEmitCatch):
      (JSC::BytecodeGenerator::emitPushNameScope):
      (JSC::BytecodeGenerator::isArgumentNumber):
      * bytecompiler/BytecodeGenerator.h:
      (JSC::Local::Local):
      (JSC::Local::operator bool):
      (JSC::Local::get):
      (JSC::Local::isReadOnly):
      (JSC::BytecodeGenerator::scopeDepth):
      (JSC::BytecodeGenerator::shouldOptimizeLocals):
      (JSC::BytecodeGenerator::canOptimizeNonLocals): Refactored the bytecode
      generator to resolve all variables within local scope, as if there
      were no non-local scope. This helps provide a separation of concerns:
      unlinked bytecode is always scope-free, and the linking stage links
      in the provided scope.
      
      * bytecompiler/NodesCodegen.cpp:
      (JSC::ResolveNode::isPure):
      (JSC::ResolveNode::emitBytecode):
      (JSC::EvalFunctionCallNode::emitBytecode):
      (JSC::FunctionCallResolveNode::emitBytecode):
      (JSC::PostfixNode::emitResolve):
      (JSC::DeleteResolveNode::emitBytecode):
      (JSC::TypeOfResolveNode::emitBytecode):
      (JSC::PrefixNode::emitResolve):
      (JSC::ReadModifyResolveNode::emitBytecode):
      (JSC::AssignResolveNode::emitBytecode):
      (JSC::ConstDeclNode::emitCodeSingle):
      (JSC::ForInNode::emitBytecode): A bunch of this codegen is no longer
      necessary, since it's redundant with the linking stage.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::ByteCodeParser):
      (JSC::DFG::ByteCodeParser::cellConstantWithStructureCheck):
      (JSC::DFG::ByteCodeParser::handlePutByOffset):
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseBlock): Updated for interface changes.
      Notably, we can reuse existing DFG nodes -- but the mapping between
      bytecode and DFG nodes has changed, and some nodes and corner cases have
      been removed.
      
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::scopedVarLoadElimination):
      (JSC::DFG::CSEPhase::varInjectionWatchpointElimination):
      (JSC::DFG::CSEPhase::globalVarStoreElimination):
      (JSC::DFG::CSEPhase::scopedVarStoreElimination):
      (JSC::DFG::CSEPhase::getLocalLoadElimination):
      (JSC::DFG::CSEPhase::setLocalStoreElimination):
      (JSC::DFG::CSEPhase::performNodeCSE): Added CSE for var injection
      watchpoints. Even though watchpoints are "free", they're quite common
      inside code that's subject to var injection, so I figured we'd save a
      little memory.
      
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGCapabilities.h: Removed detection for old forms.
      
      * dfg/DFGDriver.h:
      (JSC::DFG::tryCompile):
      (JSC::DFG::tryCompileFunction):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.h:
      * dfg/DFGJITCode.cpp:
      * dfg/DFGNode.h:
      (JSC::DFG::Node::convertToStructureTransitionWatchpoint):
      (JSC::DFG::Node::hasVarNumber):
      (JSC::DFG::Node::hasIdentifierNumberForCheck):
      (JSC::DFG::Node::hasRegisterPointer):
      (JSC::DFG::Node::hasHeapPrediction):
      * dfg/DFGNodeType.h:
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGRepatch.h:
      (JSC::DFG::dfgResetGetByID):
      (JSC::DFG::dfgResetPutByID):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation): Removed some unneeded things,
      and updated for renames.
      
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile): The two primary changes here are:
      
      (1) Use a watchpoint for var injection instead of looping over the scope
      chain and checking. This is more efficient and much easier to model in
      code generation.
      
      (2) I've eliminated the notion of an optimized global assignment that
      needs to check for whether it should fire a watchpiont. Instead, we
      fire pre-emptively at the point of optimization. This removes a bunch
      of edge cases, and it seems like a more honest representation of
      the fact that our new optimization contradicts our old one.
      
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      * heap/DFGCodeBlocks.cpp:
      (JSC::DFGCodeBlocks::jettison):
      * interpreter/CallFrame.h:
      (JSC::ExecState::trueCallFrame): Removed stuff that's unused now, and
      fixed the build.
      
      * interpreter/Interpreter.cpp:
      (JSC::eval):
      (JSC::getBytecodeOffsetForCallFrame):
      (JSC::getCallerInfo):
      (JSC::Interpreter::throwException): Updated exception scope tracking
      to match the rest of our linking strategy: The unlinked bytecode compiles
      exception scope as if non-local scope did not exist, and we add in
      non-local scope at link time. This means that we can restore the right
      scope depth based on a simple number, without checking the contents of
      the scope chain.
      
      (JSC::Interpreter::execute): Make sure to establish the full scope chain
      before linking eval code. We now require the full scope chain at link
      time, in order to link non-local variable resolution opcodes.
      
      * jit/JIT.cpp:
      (JSC::JIT::JIT):
      (JSC::JIT::privateCompileMainPass):
      (JSC::JIT::privateCompileSlowCases):
      * jit/JIT.h:
      * jit/JITArithmetic.cpp:
      (JSC::JIT::emit_op_add):
      * jit/JITCode.cpp:
      * jit/JITOpcodes.cpp:
      (JSC::JIT::emitSlow_op_bitxor):
      (JSC::JIT::emitSlow_op_bitor):
      * jit/JITOpcodes32_64.cpp:
      (JSC::JIT::emitSlow_op_to_primitive):
      (JSC::JIT::emit_op_strcat):
      (JSC::JIT::emitSlow_op_create_this):
      (JSC::JIT::emitSlow_op_to_this):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::emitVarInjectionCheck):
      (JSC::JIT::emitResolveClosure):
      (JSC::JIT::emit_op_resolve_scope):
      (JSC::JIT::emitSlow_op_resolve_scope):
      (JSC::JIT::emitLoadWithStructureCheck):
      (JSC::JIT::emitGetGlobalProperty):
      (JSC::JIT::emitGetGlobalVar):
      (JSC::JIT::emitGetClosureVar):
      (JSC::JIT::emit_op_get_from_scope):
      (JSC::JIT::emitSlow_op_get_from_scope):
      (JSC::JIT::emitPutGlobalProperty):
      (JSC::JIT::emitPutGlobalVar):
      (JSC::JIT::emitPutClosureVar):
      (JSC::JIT::emit_op_put_to_scope):
      (JSC::JIT::emitSlow_op_put_to_scope):
      (JSC::JIT::emit_op_init_global_const):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::emitVarInjectionCheck):
      (JSC::JIT::emitResolveClosure):
      (JSC::JIT::emit_op_resolve_scope):
      (JSC::JIT::emitSlow_op_resolve_scope):
      (JSC::JIT::emitLoadWithStructureCheck):
      (JSC::JIT::emitGetGlobalProperty):
      (JSC::JIT::emitGetGlobalVar):
      (JSC::JIT::emitGetClosureVar):
      (JSC::JIT::emit_op_get_from_scope):
      (JSC::JIT::emitSlow_op_get_from_scope):
      (JSC::JIT::emitPutGlobalProperty):
      (JSC::JIT::emitPutGlobalVar):
      (JSC::JIT::emitPutClosureVar):
      (JSC::JIT::emit_op_put_to_scope):
      (JSC::JIT::emitSlow_op_put_to_scope):
      (JSC::JIT::emit_op_init_global_const):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * jit/JITStubs.h: Re-wrote baseline JIT codegen for our new variable
      resolution model.
      
      * llint/LLIntData.cpp:
      (JSC::LLInt::Data::performAssertions):
      * llint/LLIntSlowPaths.cpp:
      * llint/LLIntSlowPaths.h:
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter.cpp:
      (JSC::CLoop::execute):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm: Ditto for LLInt.
      
      * offlineasm/x86.rb: Fixed a pre-existing encoding bug for a syntactic
      form that we never used before.
      
      * runtime/ArrayPrototype.cpp:
      (JSC::arrayProtoFuncToString):
      (JSC::arrayProtoFuncToLocaleString):
      (JSC::arrayProtoFuncJoin):
      (JSC::arrayProtoFuncConcat):
      (JSC::arrayProtoFuncPop):
      (JSC::arrayProtoFuncPush):
      (JSC::arrayProtoFuncReverse):
      (JSC::arrayProtoFuncShift):
      (JSC::arrayProtoFuncSlice):
      (JSC::arrayProtoFuncSort):
      (JSC::arrayProtoFuncSplice):
      (JSC::arrayProtoFuncUnShift):
      (JSC::arrayProtoFuncFilter):
      (JSC::arrayProtoFuncMap):
      (JSC::arrayProtoFuncEvery):
      (JSC::arrayProtoFuncForEach):
      (JSC::arrayProtoFuncSome):
      (JSC::arrayProtoFuncReduce):
      (JSC::arrayProtoFuncReduceRight):
      (JSC::arrayProtoFuncIndexOf):
      (JSC::arrayProtoFuncLastIndexOf): Fixed some pre-existing bugs in
      'this' value conversion, which I made much more common by removing
      special cases in bytecode generation.
      
      These functions need to invoke toThis() because they observe the 'this'
      value. Also, toLocaleString() is specified to accept non-array 'this'
      values.
      
      (Most other host functions don't need this fix because they perform
      strict 'this' checking, which never coerces unexpected types.)
      
      * runtime/CodeCache.cpp:
      (JSC::CodeCache::getCodeBlock):
      (JSC::CodeCache::getProgramCodeBlock):
      (JSC::CodeCache::getEvalCodeBlock):
      * runtime/CodeCache.h: Don't supply a scope to the unlinked code cache.
      Unlinked code is supposed to be scope-free, so let's have the compiler
      help verify that.
      
      * runtime/CommonSlowPaths.cpp:
      (JSC::SLOW_PATH_DECL):
      * runtime/CommonSlowPaths.h:
      * runtime/Executable.cpp:
      (JSC::EvalExecutable::create):
      (JSC::EvalExecutable::compileInternal):
      (JSC::ProgramExecutable::compileInternal):
      (JSC::FunctionExecutable::produceCodeBlockFor):
      (JSC::FunctionExecutable::compileForCallInternal):
      (JSC::FunctionExecutable::compileForConstructInternal):
      * runtime/Executable.h:
      (JSC::EvalExecutable::numVariables):
      (JSC::EvalExecutable::numberOfFunctionDecls):
      * runtime/ExecutionHarness.h:
      (JSC::prepareForExecutionImpl):
      (JSC::prepareFunctionForExecutionImpl):
      (JSC::installOptimizedCode): Fiddled with executable initialization so
      that we can always generate a full scope chain before we go to link a
      code block. We need this because code block linking now depends on the
      scope chain to link non-local variable resolution opcodes.
      
      * runtime/JSActivation.h:
      * runtime/JSGlobalObject.cpp:
      (JSC::JSGlobalObject::JSGlobalObject):
      (JSC::JSGlobalObject::createEvalCodeBlock):
      * runtime/JSGlobalObject.h:
      (JSC::JSGlobalObject::varInjectionWatchpoint):
      * runtime/JSGlobalObjectFunctions.cpp:
      (JSC::globalFuncEval):
      * runtime/JSNameScope.h:
      * runtime/JSScope.cpp:
      (JSC::abstractAccess):
      (JSC::JSScope::objectAtScope):
      (JSC::JSScope::depth):
      (JSC::JSScope::resolve):
      (JSC::JSScope::abstractResolve): Updated to match changes explained above.
      
      * runtime/JSScope.h:
      (JSC::makeType):
      (JSC::needsVarInjectionChecks):
      (JSC::ResolveOp::ResolveOp):
      (JSC::ResolveModeAndType::ResolveModeAndType):
      (JSC::ResolveModeAndType::mode):
      (JSC::ResolveModeAndType::type):
      (JSC::ResolveModeAndType::operand): Removed the old variable resolution
      state machine, since it's unused now. Added logic for performing abstract
      variable resolution at link time. This is used by codeblock linking.
      
      * runtime/ObjectPrototype.cpp:
      (JSC::objectProtoFuncValueOf):
      (JSC::objectProtoFuncHasOwnProperty):
      (JSC::objectProtoFuncIsPrototypeOf):
      (JSC::objectProtoFuncDefineGetter):
      (JSC::objectProtoFuncDefineSetter):
      (JSC::objectProtoFuncLookupGetter):
      (JSC::objectProtoFuncLookupSetter):
      (JSC::objectProtoFuncPropertyIsEnumerable):
      (JSC::objectProtoFuncToLocaleString):
      (JSC::objectProtoFuncToString): Fixed some pre-existing bugs in
      'this' value conversion, which I made much more common by removing
      special cases in bytecode generation.
      
      These functions need to invoke toThis() because they observe the 'this'
      value.
      
      * runtime/StringPrototype.cpp:
      (JSC::checkObjectCoercible):
      (JSC::stringProtoFuncReplace):
      (JSC::stringProtoFuncCharAt):
      (JSC::stringProtoFuncCharCodeAt):
      (JSC::stringProtoFuncConcat):
      (JSC::stringProtoFuncIndexOf):
      (JSC::stringProtoFuncLastIndexOf):
      (JSC::stringProtoFuncMatch):
      (JSC::stringProtoFuncSearch):
      (JSC::stringProtoFuncSlice):
      (JSC::stringProtoFuncSplit):
      (JSC::stringProtoFuncSubstr):
      (JSC::stringProtoFuncSubstring):
      (JSC::stringProtoFuncToLowerCase):
      (JSC::stringProtoFuncToUpperCase):
      (JSC::stringProtoFuncLocaleCompare):
      (JSC::stringProtoFuncBig):
      (JSC::stringProtoFuncSmall):
      (JSC::stringProtoFuncBlink):
      (JSC::stringProtoFuncBold):
      (JSC::stringProtoFuncFixed):
      (JSC::stringProtoFuncItalics):
      (JSC::stringProtoFuncStrike):
      (JSC::stringProtoFuncSub):
      (JSC::stringProtoFuncSup):
      (JSC::stringProtoFuncFontcolor):
      (JSC::stringProtoFuncFontsize):
      (JSC::stringProtoFuncAnchor):
      (JSC::stringProtoFuncLink):
      (JSC::trimString): Fixed some pre-existing bugs in
      'this' value conversion, which I made much more common by removing
      special cases in bytecode generation.
      
      These functions need to invoke toThis() because they observe the 'this'
      value.
      
      * runtime/StructureRareData.cpp:
      * runtime/VM.cpp:
      (JSC::VM::~VM):
      
      * runtime/WriteBarrier.h:
      (JSC::WriteBarrierBase::slot): Modified to reduce casting in client code.
      
      LayoutTests:
      
      This patch removed special-case 'this' resolution from bytecode, making
      some pre-existing edge cases in 'this' value treatment much more common.
      
      I updated the test results below, and added some tests, to match bug
      fixes for these cases.
      
      * fast/js/script-tests/array-functions-non-arrays.js:
      * fast/js/array-functions-non-arrays-expected.txt: As specified, it's
      not an error to pass a non-array to toLocaleString. Our new result
      matches Firefox and Chrome.
      
      * fast/js/array-prototype-properties-expected.txt: Updated for slightly
      clearer error message.
      
      * fast/js/basic-strict-mode-expected.txt: Updated for slightly more
      standard error message.
      
      * fast/js/object-prototype-toString-expected.txt: Added.
      * fast/js/object-prototype-toString.html: Added. This test demonstrates
      why we now fail a Sputnik test below, while Firefox and Chrome pass it.
      (The test doesn't test what it thinks it tests, and this test verifies
      that we get right what it does think it tests.)
      
      * fast/js/string-prototype-function-this-expected.txt: Added.
      * fast/js/string-prototype-function-this.html: Added. This test shows
      that we CheckObjectCoercible in string prototype functions. (We used
      to get this wrong, but Sputnik tests made it seem like we got it right
      because they didn't test the dynamic scope case.)
      
      * sputnik/Conformance/11_Expressions/11.1_Primary_Expressions/11.1.1_The_this_Keyword/S11.1.1_A2-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.3_Array_prototype_toLocaleString/S15.4.4.3_A2_T1-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.11_String.prototype.replace/S15.5.4.11_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.12_String.prototype.search/S15.5.4.12_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.13_String.prototype.slice/S15.5.4.13_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.15_String.prototype.substring/S15.5.4.15_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.6_String.prototype.concat/S15.5.4.6_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.7_String.prototype.indexOf/S15.5.4.7_A1_T3-expected.txt:
      * sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.8_String.prototype.lastIndexOf/S15.5.4.8_A1_T3-expected.txt:
      
      Updated to show failing results. Firefox and Chrome also fail these
      tests, and the ES5 spec seems to mandate failure. Because these tests
      resolve a String.prototype function at global scope, the 'this' value
      for the call is an environment record. Logically, an environment record
      converts to 'undefined' at the call site, and should then fail the
      CheckObjectCoercible test.
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153221 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      58c86752
    • oliver@apple.com's avatar
      fourthTier: isContravenedByStructure is backwards · d05719a4
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117366
      
      We should be checking if arrayModeForStructure(structure) is a
      subset of arrayModesThatPassFiltering(), not the other way around.
      Also renamed isContravenedByStructure to better reflect what the
      function is trying to determine.
      
      Rubber stamped by Filip Pizlo.
      
      * dfg/DFGArrayMode.h:
      (JSC::DFG::ArrayMode::structureWouldPassArrayModeFiltering):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheckAccountingForArrayMode):
      (JSC::DFG::ArrayTypeCheck::isContravenedByValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153220 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d05719a4
    • oliver@apple.com's avatar
      fourthTier: Type check hoisting phase has a dead if statement · 75d8e086
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117510
      
      Reviewed by Geoffrey Garen.
      
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153219 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      75d8e086
    • oliver@apple.com's avatar
      fourthTier: Introducing the StackIterator class. · 2b2e1324
      oliver@apple.com authored
      This was a non trivial merge as trunk has changed computation of line and column information
      
      Introducing the StackIterator class.
      https://bugs.webkit.org/show_bug.cgi?id=117390.
      
      Reviewed by Geoffrey Garen.
      
      Source/JavaScriptCore:
      
      The StackIterator class is meant to unify the way we iterate the JS
      stack. It also makes it so that we don't have to copy the frame data
      into the intermediate StackFrame struct before processing it.
      Unfortunately we still can't get rid of StackFrame because it is used
      to record frame information for the Exception stack that is expected
      to persist beyond when the frames have been popped off the JS stack.
      
      The StackIterator will iterate over all "logical" frames (i.e. including
      inlined frames). As it iterates the JS stack, if it encounters a DFG
      frame that has inlined frames, the iterator will canonicalize the
      inlined frames before returning. Once canonicalized, the frame can be
      read like any other frame.
      
      The StackIterator implements a Frame class that inherits from CallFrame.
      The StackIterator::Frame serves as reader of the CallFrame that makes
      it easier to access information about the frame. The StackIterator::Frame
      only adds functions, and no additional data fields.
      
      * API/JSContextRef.cpp:
      (JSContextCreateBacktrace):
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::begin):
      (JSC::CallFrame::beginAt):
      * interpreter/CallFrame.h:
      (JSC::ExecState::setInlineCallFrame):
      (ExecState):
      (JSC::ExecState::end):
      * interpreter/Interpreter.cpp:
      (JSC::Interpreter::dumpRegisters):
      (JSC::Interpreter::unwindCallFrame):
      (JSC::Interpreter::getStackTrace):
      (JSC::Interpreter::throwException):
      (JSC::Interpreter::debug):
      * interpreter/Interpreter.h:
      (Interpreter):
      * interpreter/StackIterator.cpp: Added.
      (JSC::StackIterator::StackIterator):
      (JSC::StackIterator::beginAt):
      (JSC::StackIterator::gotoNextFrame):
      - Based on the deleted Interpreter::findFunctionCallFrameFromVMCode().
      (JSC::StackIterator::findFrameForFunction):
      - Based on the deleted Interpreter::retrieveCallerFromVMCode().
      (JSC::StackIterator::Frame::codeType):
      - Based on the deleted getStackFrameCodeType().
      (JSC::StackIterator::Frame::functionName):
      - Based on StackFrame::friendlyFunctionName().
      (JSC::StackIterator::Frame::sourceURL):
      - Based on StackFrame::friendlySourceURL().
      (JSC::StackIterator::Frame::toString):
      - Based on StackFrame::toString().
      (JSC::StackIterator::Frame::bytecodeOffset):
      (JSC::StackIterator::Frame::line):
      - Based on StackFrame::line().
      (JSC::StackIterator::Frame::column):
      - Based on StackFrame::column().
      (JSC::StackIterator::Frame::arguments):
      - Based on the deleted Interpreter::retrieveArgumentsFromVMCode().
      (JSC::StackIterator::Frame::retrieveExpressionInfo):
      - Based on StackFrame::expressionInfo().
      (JSC::StackIterator::Frame::logicalFrame):
      - Based on the now deleted CallFrame::trueCallFrame().
      (JSC::StackIterator::Frame::logicalCallerFrame):
      - Based on the now deleted CallFrame::trueCallerFrame().
      (JSC::jitTypeName):
      (JSC::printIndents):
      (JSC::printif):
      (JSC::StackIterator::Frame::print):
      (debugPrintCallFrame):
      - Prints the contents of the frame for debugging purposes.
        There are 2 versions that can be used as follows:
      
        1. When you have a valid StackIterator, you can print
           the current frame's content using the print instance
           method:
               iter->print(indentLevel);
      
        2. When you have a CallFrame* that you want to dump from a debugger
           console, you can print its content as follows:
               (gdb) call debugPrintCallFrame(callFrame)
      
        A sample of the output looks like this:
      
            frame 0x1510c70b0 {
               name 'shouldBe'
               sourceURL 'testapi.js'
               hostFlag 0
               isInlinedFrame 0
               callee 0x15154efb0
               returnPC 0x10ed0786d
               callerFrame 0x1510c7058
               logicalCallerFrame 0x1510c7058
               rawLocationBits 27 0x1b
               codeBlock 0x7fe79b037200
                  bytecodeOffset 27 0x1b / 210
                  line 46
                  column 20
                  jitType 3 <BaselineJIT> isOptimizingJIT 0
                  hasCodeOrigins 0
            }
      
      * interpreter/StackIterator.h: Added.
      (StackIterator::Frame):
      (JSC::StackIterator::Frame::create):
      (JSC::StackIterator::Frame::isJSFrame):
      (JSC::StackIterator::Frame::callFrame):
      * interpreter/StackIteratorPrivate.h: Added.
      (StackIterator):
      (JSC::StackIterator::operator*):
      (JSC::StackIterator::operator->):
      (JSC::StackIterator::operator==):
      (JSC::StackIterator::operator!=):
      (JSC::StackIterator::operator++):
      (JSC::StackIterator::end):
      (JSC::StackIterator::empty):
      * jsc.cpp:
      (functionJSCStack):
      * profiler/ProfileGenerator.cpp:
      (JSC::ProfileGenerator::addParentForConsoleStart):
      * profiler/ProfileNode.h:
      (ProfileNode):
      * runtime/JSFunction.cpp:
      (JSC::retrieveArguments):
      (JSC::JSFunction::argumentsGetter):
      (JSC::skipOverBoundFunctions):
      (JSC::retrieveCallerFunction):
      (JSC::JSFunction::callerGetter):
      (JSC::JSFunction::getOwnPropertyDescriptor):
      (JSC::JSFunction::defineOwnProperty):
      * runtime/JSGlobalObjectFunctions.cpp:
      (JSC::globalFuncProtoGetter):
      (JSC::globalFuncProtoSetter):
      * runtime/ObjectConstructor.cpp:
      (JSC::objectConstructorGetPrototypeOf):
      * runtime/Operations.h:
      
      Source/WebCore:
      
      No new tests.
      
      * ForwardingHeaders/interpreter/StackIterator.h: Added.
      * bindings/js/JSXMLHttpRequestCustom.cpp:
      (WebCore::JSXMLHttpRequest::send):
      * bindings/js/ScriptCallStackFactory.cpp:
      (WebCore::createScriptCallStack):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153218 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      2b2e1324
    • oliver@apple.com's avatar
      fourthTier: DFG GetById patching shouldn't distinguish between self lists and proto lists · 73823ba8
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117377
      
      Source/JavaScriptCore:
      
      Reviewed by Geoffrey Garen.
      
      Previously if you did self accesses and then wanted to do a prototype access, you'd
      have a bad time: the prototype accesses would be forced to take slow path because
      the self list wouldn't allow prototype accesses. Likewise if you did prototype (or
      chain) accesses and then wanted to do a self access, similar stupidity would ensue.
      
      This fixes the stupidity.
      
      I believe that this was introduced way back in the days of the old interpreter,
      where distinguishing between self lists, proto lists, and chain lists was meaningful
      for interpreter performance: it meant fewer branches to evaluate those lists. Then
      it got mostly carried over to the old JIT since the old JIT was just initially an
      optimized version of the old interpreter, and then later it got carried over to the
      DFG because I didn't know any better at the time. Now I do know better and I'm
      fixing it.
      
      * bytecode/PolymorphicAccessStructureList.h:
      (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
      * bytecode/StructureStubInfo.h:
      (JSC::StructureStubInfo::initGetByIdSelfList):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::tryCacheGetByID):
      (JSC::DFG::getPolymorphicStructureList):
      (DFG):
      (JSC::DFG::patchJumpToGetByIdStub):
      (JSC::DFG::tryBuildGetByIDList):
      (JSC::DFG::dfgBuildGetByIDList):
      
      LayoutTests:
      
      Reviewed by Geoffrey Garen.
      
      Add tests that show why this is important. These tests speed up by more than 3x.
      
      * fast/js/regress/get-by-id-proto-or-self-expected.txt: Added.
      * fast/js/regress/get-by-id-proto-or-self.html: Added.
      * fast/js/regress/get-by-id-self-or-proto-expected.txt: Added.
      * fast/js/regress/get-by-id-self-or-proto.html: Added.
      * fast/js/regress/script-tests/get-by-id-proto-or-self.js: Added.
      (foo):
      (bar):
      (Foo):
      * fast/js/regress/script-tests/get-by-id-self-or-proto.js: Added.
      (foo):
      (bar):
      (Foo):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153217 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      73823ba8
    • oliver@apple.com's avatar
      fourthTier: Recursive deadlock in DFG::ByteCodeParser · 0919f4f3
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117376
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Leave the lock early to prevent a deadlock beneath get().
      
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      I've often wanted to leave a lock early. Now I have that power!
      
      * wtf/Locker.h:
      (WTF::Locker::Locker):
      (WTF::Locker::~Locker):
      (Locker):
      (WTF::Locker::unlockEarly):
      (WTF::Locker::lock):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153216 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0919f4f3
    • oliver@apple.com's avatar
      fourthTier: don't insert ForceOSRExits except for inadequate coverage · 37bd9382
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117363
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Previously (in http://trac.webkit.org/changeset/151303) I made it so that we
      inserted ForceOSRExits more eagerly.  I now think it's better to have
      contradictions execute normally and exit with full OSR exit profiling.  It's
      better at catching the few cases where the DFG will end up with different
      types than the baseline engines.
      
      This simplifies a bunch of code. For example it gets rid of
      ConstantFoldingPhase::paintUnreachableCode().
      
      You can think of this as a partial roll-out of r151303, except that it uses
      the facilities introduced by that patch to give us run-time assertions that
      check the CFA's correctness: if the CFA thought that something was a
      contradiction but the code didn't exit, we'll now trap.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::AbstractState):
      (JSC::DFG::AbstractState::startExecuting):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::filter):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      (DFG):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      (JSC::DFG::AbstractState::filter):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::performBlockCFA):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::run):
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (ConstantFoldingPhase):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      Convert this test, since this was the test originally added for
      ConstantFoldingPhase::paintUnreachableCode(). I wanted to make sure that I had good coverage
      for this since I am removing that method.
      
      * fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop-expected.txt:
      * fast/js/script-tests/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153215 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      37bd9382
    • oliver@apple.com's avatar
      fourthTier: Reenable the DFG optimization fixpoint now that it's profitable to... · 8b3558be
      oliver@apple.com authored
      fourthTier: Reenable the DFG optimization fixpoint now that it's profitable to do so with concurrent compilation
      https://bugs.webkit.org/show_bug.cgi?id=117331
      
      Rubber stamped by Sam Weinig.
      
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153214 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      8b3558be
    • oliver@apple.com's avatar
      fourthTier: DFG CFA should know when it hits a contradiction · 3391387e
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117272
      
      Reviewed by Oliver Hunt.
      
      This makes the DFG CFA immediately detect when it hit a contradiction. Previously
      we might not know this: for example if we did an int32 type check on a known string;
      the code would definitely always exit but the CFA would think that we wouldn't have
      even though it would have computed a BOTTOM (i.e. contradictory) value for that
      variable.
      
      This requires two other changes:
      
      - CFA must report contradictions as if they are frequent exit sites, since
        contradictory speculations will subsequently get replaced with ForceOSRExit.
        ForceOSRExit cannot itself report profiling data back to the DFG::ExitProfile. So,
        we do this on behalf of the speculation, eagerly, within the CFA. This also has
        the effect of speeding convergence somewhat. We may want to revisit this later;
        for example we might want to instead have the notion of a ForceOSRExit that knows
        the set of speculations that got folded into it.
      
      - This revealed a bug where the CFA was modeling CheckStructure on a node that had
        a known singleton m_futurePossibleStructure set somewhat differently than the
        constant folder. If the CheckStructure was checking a structure set with two or
        more structures in it, it would not filter the abstract value. But the constant
        folder would turn this into a watchpoint on the singleton structure, thereby
        filtering the value. This discrepancy meant that we wouldn't realize the
        contradiction until the backend, and the AbstractState::bail() method asserts that
        we always realize contradictions in the constant folder.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::addFrequentExitSite):
      (JSC::CodeBlock::hasExitSite):
      (CodeBlock):
      * bytecode/DFGExitProfile.cpp:
      (JSC::DFG::ExitProfile::add):
      (JSC::DFG::ExitProfile::hasExitSite):
      (JSC::DFG::QueryableExitProfile::QueryableExitProfile):
      (JSC::DFG::QueryableExitProfile::~QueryableExitProfile):
      (DFG):
      (JSC::DFG::QueryableExitProfile::initialize):
      * bytecode/DFGExitProfile.h:
      (JSC::DFG::FrequentExitSite::FrequentExitSite):
      (ExitProfile):
      (JSC::DFG::ExitProfile::hasExitSite):
      (QueryableExitProfile):
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::AbstractState):
      (JSC::DFG::AbstractState::beginBasicBlock):
      (JSC::DFG::AbstractState::reset):
      (JSC::DFG::AbstractState::startExecuting):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::execute):
      (JSC::DFG::AbstractState::filter):
      (DFG):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      (JSC::DFG::AbstractState::bail):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      (JSC::DFG::AbstractState::filter):
      (JSC::DFG::AbstractState::filterArrayModes):
      (JSC::DFG::AbstractState::filterByValue):
      (JSC::DFG::AbstractState::filterByType):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::filter):
      (JSC::DFG::AbstractValue::filterArrayModes):
      (DFG):
      (JSC::DFG::AbstractValue::filterByValue):
      (JSC::DFG::AbstractValue::normalizeClarity):
      * dfg/DFGAbstractValue.h:
      (AbstractValue):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::performBlockCFA):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::debugFail):
      (JSC::DFG::capabilityLevel):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (ConstantFoldingPhase):
      (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
      * dfg/DFGFiltrationResult.h: Added.
      (DFG):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOSRExitBase.cpp:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitBase.h:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::backwardTypeCheck):
      (JSC::DFG::SpeculativeJIT::bail):
      (DFG):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
      (JSC::DFG::SpeculativeJIT::speculateStringObject):
      (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::appendTypeCheck):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153213 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      3391387e
    • oliver@apple.com's avatar
      fourthTier: 32-bit CallFrame::Location should use Instruction* for... · c4c9b8a1
      oliver@apple.com authored
      fourthTier: 32-bit CallFrame::Location should use Instruction* for BytecodeLocation, not bytecodeOffset.
      https://bugs.webkit.org/show_bug.cgi?id=117327.
      
      Reviewed by Michael Saboff.
      
      - Renamed CallFrame::Location's Type to TypeTag.
      - Made the CallFrame::Location::TypeTag private, and provided type
        specific encoder functions. This reduces verbosity in client code.
      - Fixed the DFG's reifyInlinedCallFrames() on 32-bit ports to store a
        bytecode Instruction* in the CallFrame location instead of a bytecode
        offset.
      - Fixed places in JIT and FTL code which populate the CallFrame location
        (i.e. ArgumentCount tag) to use a Location encoder instead of storing
        the bytecodeOffset directly. This doesn't make any semantic difference,
        but it does assert that the stored value does not have bits where we
        would expect Location TypeTags to be.
      
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::beginCall):
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::reifyInlinedCallFrames):
      * ftl/FTLLink.cpp:
      (JSC::FTL::link):
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      * interpreter/CallFrame.h:
      (Location):
      * interpreter/CallFrameInlines.h:
      (JSC::CallFrame::Location::encodeAsBytecodeOffset):
      (JSC::CallFrame::Location::encodeAsBytecodeInstruction):
      (JSC::CallFrame::Location::encodeAsCodeOriginIndex):
      (JSC::CallFrame::Location::encodeAsInlinedCode):
      (JSC::CallFrame::Location::isBytecodeLocation):
      (JSC::CallFrame::setIsInlinedFrame):
      (JSC::CallFrame::hasLocationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      * jit/JITCall.cpp:
      (JSC::JIT::compileOpCall):
      * jit/JITCall32_64.cpp:
      (JSC::JIT::compileOpCall):
      * jit/JITInlines.h:
      (JSC::JIT::updateTopCallFrame):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153212 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c4c9b8a1
    • oliver@apple.com's avatar
      fourthTier: CallFrame::trueCallFrame() should populate the bytecodeOffset field · 1e7b6b5d
      oliver@apple.com authored
      when reifying inlined frames..
      https://bugs.webkit.org/show_bug.cgi?id=117209.
      
      Reviewed by Geoffrey Garen.
      
      When reifying an inlined frame, we fill in its CodeBlock, and
      bytecodeOffset. We also set the InlinedFrame bit in the location field.
      This is needed in order to iterate the stack correctly. Here's why:
      
          Let's say we have the following stack trace:
            X calls A inlines B inlines C calls D
      
          Based on the above scenario,
          1. D's callerFrame points to A (not C).
          2. A has a codeOriginIndex that points to C.
      
      When iterating the stack (from D back towards X), we will encounter A
      twice:
      
          t1. when trying to find C as D's caller.
              This is the time when we reify B and C using the
              codeOriginIndex in A, and return C as the caller frame of D.
      
          t2. when getting's the reified B's caller.
              This time, we don't run the reification process, and
              just take A as the caller frame of B.
      
      To discern which treatment of the DFG frame (i.e. A) we need to apply,
      we check if the callee is an inlined frame:
      
          If callee is NOT an inlined frame (e.g. frame D), apply treatment t1.
          If callee is an inlined frame (e.g. frame B), apply treatment t2.
      
      Why not just reify A by replacing its codeOriginIndex with A's
      bytecodeOffset?
      
      We can't do this because D's callerFrame pointer still points to A, and
      needs to remain that way because we did not deopt A. It remains a DFG
      frame which inlined B and C.
      
      If we replace the codeOriginIndex in A with A's bytecodeOffset, we will
      only get to iterate the stack correctly once. If we try to iterate the
      stack a second time, we will not have the information from the
      codeOriginIndex to tell us that D's caller is actually the inlined C,
      and not A.
      
      To recap, when reifying frames for stack iteration purposes, the DFG
      frame needs to hold on to its codeOriginIndex. This in turn means the
      DFG frame will need to be treated in 2 possible ways, and we need to
      know if a callee frame is an inlined frame in order to choose the
      correct treatment for the DFG frame.
      
      Other changes:
      - Simplified Interpreter::getCallerInfo().
      - Removed CodeBlock::codeOriginForReturn() and supporting code
        which is now unneeded.
      - Moved CallFrame location bit encoding from the CodeOrigin to the
        new CallFrame::Location class.
      - Explicitly tagged inlined frames. This is necessary in order to
        iterate the stack correctly as explained above.
      
      * bytecode/CodeBlock.cpp:
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::codeOrigins):
      (CodeBlock):
      (JSC::CodeBlock::codeOrigin):
      (RareData):
      * bytecode/CodeOrigin.h:
      (CodeOrigin):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::beginCall):
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::trueCallFrame):
      (JSC::CallFrame::trueCallerFrame):
      (JSC::CallFrame::bytecodeOffsetFromCodeOriginIndex):
      * interpreter/CallFrame.h:
      (Location):
      (ExecState):
      (JSC::ExecState::trueCallerFrame):
      (JSC::ExecState::callerFrameNoFlags):
      * interpreter/CallFrameInlines.h:
      (JSC::CallFrame::Location::encode):
      (JSC::CallFrame::Location::decode):
      (JSC::CallFrame::Location::isBytecodeOffset):
      (JSC::CallFrame::Location::isCodeOriginIndex):
      (JSC::CallFrame::Location::isInlinedFrame):
      (JSC::CallFrame::isInlinedFrame):
      (JSC::CallFrame::setIsInlinedFrame):
      (JSC::CallFrame::hasLocationAsBytecodeOffset):
      (JSC::CallFrame::hasLocationAsCodeOriginIndex):
      (JSC::CallFrame::locationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      (JSC::CallFrame::locationAsCodeOriginIndex):
      * interpreter/Interpreter.cpp:
      (JSC::getCallerInfo):
      (JSC::Interpreter::getStackTrace):
      (JSC::Interpreter::findFunctionCallFrameFromVMCode):
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOff):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153211 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1e7b6b5d
    • oliver@apple.com's avatar
      fourthTier: DFG CFA shouldn't filter ArrayModes with ALL_NON_ARRAY_ARRAY_MODES... · afa7e3aa
      oliver@apple.com authored
      fourthTier: DFG CFA shouldn't filter ArrayModes with ALL_NON_ARRAY_ARRAY_MODES if the speculated type is not SpecArray
      https://bugs.webkit.org/show_bug.cgi?id=117279
      
      Reviewed by Mark Hahnenberg.
      
      The normalization of abstract value clarity introduced in r151229 revealed a
      long-standing bug where we filtered ArrayModes incorrectly and sometimes ended
      up with BOTTOM incorrectly.
      
      This patch fixes that bug, and cleans up a bunch of debugging infrastructure
      that I needed to resurrect to track this down.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::resetStubInternal):
      (JSC::CodeBlock::noticeIncomingCall):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::filterArrayModesByType):
      * dfg/DFGCFAPhase.cpp:
      (CFAPhase):
      (JSC::DFG::CFAPhase::run):
      (JSC::DFG::CFAPhase::performBlockCFA):
      (JSC::DFG::CFAPhase::performForwardCFA):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153210 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      afa7e3aa
    • oliver@apple.com's avatar
      fourthTier: Disambiguate between CallFrame bytecodeOffset and codeOriginIndex. · c4497327
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117262.
      
      Reviewed by Geoffrey Garen.
      
      When writing to the ArgumentCount tag in CallFrame, we will set the high
      bit if the written value is a codeOriginIndex.
      
      * GNUmakefile.list.am:
      * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
      * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeOrigin.h:
      (CodeOrigin):
      (JSC::CodeOrigin::isHandle):
      (JSC::CodeOrigin::encodeHandle):
      (JSC::CodeOrigin::decodeHandle):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::beginCall):
      * dfg/DFGRepatch.cpp:
      (JSC::DFG::tryBuildGetByIDList):
      * interpreter/CallFrame.cpp:
      (JSC::CallFrame::locationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      (JSC::CallFrame::currentVPC):
      (JSC::CallFrame::setCurrentVPC):
      (JSC::CallFrame::trueCallFrame):
      * interpreter/CallFrame.h:
      (ExecState):
      (JSC::ExecState::inlineCallFrame):
      * interpreter/CallFrameInlines.h: Added.
      (JSC::CallFrame::hasLocationAsBytecodeOffset):
      (JSC::CallFrame::hasLocationAsCodeOriginIndex):
      (JSC::CallFrame::locationAsRawBits):
      (JSC::CallFrame::setLocationAsRawBits):
      (JSC::CallFrame::locationAsBytecodeOffset):
      (JSC::CallFrame::setLocationAsBytecodeOffset):
      (JSC::CallFrame::locationAsCodeOriginIndex):
      * interpreter/Interpreter.cpp:
      (JSC::getBytecodeOffsetForCallFrame):
      (JSC::getCallerInfo):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153209 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c4497327
    • oliver@apple.com's avatar
      fourthTier: Clean up AbstractValue · db4f90d9
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117217
      
      Reviewed by Oliver Hunt.
      
      This started as an attempt to make it so that when AbstractValue becomes empty,
      its m_type always becomes SpecNone. I wanted this to happen naturally. That turns
      out to be basically impossible, since AbstractValue is a set that is dynamically
      computed from the intersection of several internal sets: so the value becomes
      empty when any of the sets go empty. It's OK if we're imprecise here because it's
      always safe for the AbstractValue to seem to overapproximate the set of values
      that we see. So I mostly gave up on cleaning up that aspect of AbstractValue. But
      while trying to make this happen, I encountered two bugs:
      
      - filterValueByType() ignores the case when m_type contravenes m_value. Namely,
        we might filter the AbstractValue against a SpeculatedType leading to m_value
        becoming inconsistent with the new m_type. This change fixes that case. This
        wasn't a symptomatic bug but it was a silly oversight.
      
      - filterFuturePossibleStructure() was never right. The one call to this method,
        in filter(Graph&, const StructureSet&), assumed that the previous notions of
        what structures the value could have in the future were still relevant. This
        could lead to a bug where we:
      
        1) CheckStructure(@foo, S1)
      
           Where S1 has a valid watchpoint. Now @foo's abstract value will have current
           and future structure = S1.
      
        2) Clobber the world.
      
           Now @foo's abstract value will have current structure = TOP, and future
           possible structure = S1.
      
        3) CheckStructure(@foo, S2)
      
           Now @foo's abstract value will have current structure = S2 and future
           possible structure = S1 intersect S2 = BOTTOM.
      
        Now we will think that any subsequent watchpoint on @foo is valid because the
        value is effectively BOTTOM. That would only be correct if we had actually set
        a watchpoint on S1. If we had done so, then (3) would only pass (i.e. @foo
        would only have structure S2) if S1's watchpoint fired, in which case (3)
        wouldn't have been reachable. But we didn't actually set a watchpoint on S1:
        we just observed that we *could* have set the watchpoint. Hence future possible
        structure should only be set to either the known structure at compile-time, or
        it should be the structure we just checked; in both cases it should only be set
        if the structure is watchable.
      
      Then, in addition to all of this, I changed AbstractValue's filtering methods to
      call clear() if the AbstractValue is effectively clear. This is just meant to
      simplify the recognition of truly empty AbstractValues, but doesn't actually have
      any other implications.
      
      * bytecode/StructureSet.h:
      (JSC::StructureSet::dump):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::filter):
      (DFG):
      (JSC::DFG::AbstractValue::filterArrayModes):
      (JSC::DFG::AbstractValue::filterValueByType):
      (JSC::DFG::AbstractValue::filterArrayModesByType):
      (JSC::DFG::AbstractValue::shouldBeClear):
      (JSC::DFG::AbstractValue::normalizeClarity):
      (JSC::DFG::AbstractValue::checkConsistency):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::isClear):
      (AbstractValue):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153208 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      db4f90d9
    • oliver@apple.com's avatar
      fourthTier: The DFG JIT should populate frame bytecodeOffsets on OSR exit. · 7ddfce85
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117103.
      
      Reviewed by Geoffrey Garen.
      
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::reifyInlinedCallFrames):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153207 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      7ddfce85
    • oliver@apple.com's avatar
      fourthTier: all cached put_by_id transitions, even ones that weren't inlined... · a152471c
      oliver@apple.com authored
      fourthTier: all cached put_by_id transitions, even ones that weren't inlined by the DFG, should be propagated by the GC
      https://bugs.webkit.org/show_bug.cgi?id=117170
      
      Reviewed by Mark Hahnenberg.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::visitAggregate):
      (JSC::CodeBlock::propagateTransitions):
      (JSC):
      (JSC::CodeBlock::determineLiveness):
      (JSC::CodeBlock::visitWeakReferences):
      (JSC::CodeBlock::finalizeUnconditionally):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * bytecode/PolymorphicPutByIdList.h:
      (JSC):
      (PutByIdAccess):
      (PolymorphicPutByIdList):
      * bytecode/StructureStubInfo.h:
      (StructureStubInfo):
      * jit/JITCode.h:
      (JSC::JITCode::couldBeInterpreted):
      (JITCode):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153206 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a152471c
    • oliver@apple.com's avatar
      fourthTier: Get rid of StructureStubInfo::bytecodeIndex · 6a8125ee
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117127
      
      Reviewed by Mark Hahnenberg.
      
      StructureStubInfo already has a CodeOrigin field, which also has a bytecodeIndex.
      It makes sense to just always use the CodeOrigin.
      
      * bytecode/StructureStubInfo.h:
      (StructureStubInfo):
      (JSC::getStructureStubInfoBytecodeIndex):
      * jit/JIT.cpp:
      (JSC::PropertyStubCompilationInfo::copyToStubInfo):
      * jit/JIT.h:
      (JSC::JIT::compileGetByIdProto):
      (JSC::JIT::compileGetByIdSelfList):
      (JSC::JIT::compileGetByIdProtoList):
      (JSC::JIT::compileGetByIdChainList):
      (JSC::JIT::compileGetByIdChain):
      (JSC::JIT::compilePutByIdTransition):
      * jit/JITPropertyAccess.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      * jit/JITPropertyAccess32_64.cpp:
      (JSC::JIT::privateCompilePutByIdTransition):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153205 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6a8125ee
    • oliver@apple.com's avatar
      fourthTier: Fix some minor issues in the DFG's profiling of heap accesses · 1622cae4
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=113010
      
      Reviewed by Goeffrey Garen.
      
      Carefully merge r146669 from trunk. This required some fiddling since it
      wasn't a clean apply.
      
      Original changelog:
      
          1) If a CodeBlock gets jettisoned by GC, we should count the exit sites.
      
          2) If a CodeBlock clears a structure stub during GC, it should record this, and
          the DFG should prefer to not inline that access (i.e. treat it as if it had an
          exit site).
      
          3) If a PutById was seen by the baseline JIT, and the JIT attempted to cache it,
          but it chose not to, then assume that it will take slow path.
      
          4) If we frequently exited because of a structure check on a weak constant,
          don't try to inline that access in the future.
      
          5) Treat all exits that were counted as being frequent.
      
          81% speed-up on Octane/gbemu. Small speed-ups elsewhere, and no regressions.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::finalizeUnconditionally):
      (JSC):
      (JSC::CodeBlock::resetStubDuringGCInternal):
      (JSC::CodeBlock::reoptimize):
      (JSC::CodeBlock::jettison):
      (JSC::ProgramCodeBlock::jettisonImpl):
      (JSC::EvalCodeBlock::jettisonImpl):
      (JSC::FunctionCodeBlock::jettisonImpl):
      (JSC::CodeBlock::tallyFrequentExitSites):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      (JSC::CodeBlock::tallyFrequentExitSites):
      (ProgramCodeBlock):
      (EvalCodeBlock):
      (FunctionCodeBlock):
      * bytecode/GetByIdStatus.cpp:
      (JSC::GetByIdStatus::computeFor):
      * bytecode/PutByIdStatus.cpp:
      (JSC::PutByIdStatus::computeFor):
      * bytecode/StructureStubInfo.h:
      (JSC::StructureStubInfo::StructureStubInfo):
      (StructureStubInfo):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::handleGetById):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGOSRExitBase.cpp:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSiteSlow):
      * dfg/DFGOSRExitBase.h:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
      (OSRExitBase):
      * jit/JITStubs.cpp:
      (JSC::DEFINE_STUB_FUNCTION):
      * runtime/Options.h:
      (JSC):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153204 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      1622cae4
    • oliver@apple.com's avatar
      fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT · 382f5620
      oliver@apple.com authored
      Rubber stamped by Mark Hahnenberg.
      
      * fast/js/dfg-arguments-alias-one-block-overwrite-expected.txt:
      * fast/js/dfg-arguments-out-of-bounds-expected.txt:
      * fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int-expected.txt:
      * fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers-expected.txt:
      * fast/js/dfg-array-length-dead-expected.txt:
      * fast/js/dfg-array-pop-side-effects-expected.txt:
      * fast/js/resources/js-test-pre.js:
      (testFailed):
      (dfgIncrement):
      (isSuccessfullyParsed):
      * fast/js/script-tests/dfg-arguments-alias-one-block-overwrite.js:
      * fast/js/script-tests/dfg-arguments-out-of-bounds.js:
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js:
      * fast/js/script-tests/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js:
      * fast/js/script-tests/dfg-array-length-dead.js:
      * fast/js/script-tests/dfg-array-pop-side-effects.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153203 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      382f5620
    • oliver@apple.com's avatar
      fourthTier: Remove CodeOrigin::valueProfileOffset since it was only needed for op_call_put_result. · bc2930b5
      oliver@apple.com authored
      Rubber stamped by Mark Hahnenberg.
      
      * bytecode/CodeOrigin.h:
      (CodeOrigin):
      (JSC::CodeOrigin::CodeOrigin):
      (JSC::CodeOrigin::isSet):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::currentCodeOrigin):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::valueProfileFor):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153202 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      bc2930b5
    • oliver@apple.com's avatar
      fourthTier: Remove finalDestinationOrIgnored since it isn't called anymore. · e64543a0
      oliver@apple.com authored
      Rubber stamped by Mark Hahnenberg.
      
      * bytecompiler/BytecodeGenerator.h:
      (BytecodeGenerator):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153201 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e64543a0
    • oliver@apple.com's avatar
      fourthTier: get rid of op_call_put_result · cf0e6c40
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117047
      
      Reviewed by Gavin Barraclough.
      
      Work in progress. This still makes like 20 tests crash.
      
      op_call_put_result is an oddball. Its semantics are that it takes the return
      value of a call instruction, which is set aside in regT0/regT1, and places them
      into some stack slot. This is weird since there is an implicit contract with the
      preceding bytecode instruction, and it's even weirder since it means that it
      doesn't make sense to jump to it; for example OSR exit from the preceding call
      instruction must make sure to jump over the op_call_put_result.
      
      So this patch gets rid of op_call_put_result:
      
      - In bytecode, all calls return a value and we always allocate a temporary for
        that value even if it isn't used.
      
      - The LLInt does the return value saving as part of dispatchAfterCall().
      
      - The JIT and DFG do the return value saving as part of normal code generation.
        The DFG already did the right thing.
      
      - DFG->JIT OSR exit in the case of inlining will make the return PC's point at
        the CallLinkInfo::callReturnLocation, rather than the machine PC associated
        with the op_call_put_result instruction.
      
      - Tons of code gets removed. The DFG had to track whether or not a call had a
        return value in a bunch of places. It had to track the fact that we would
        exit to after the op_call_put_result. It was a mess. That mess is now gone.
      
      * bytecode/CallLinkStatus.cpp:
      (JSC::CallLinkStatus::computeFromLLInt):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::printCallOp):
      (JSC::CodeBlock::dumpArrayProfiling):
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::CodeBlock):
      * bytecode/CodeBlock.h:
      * bytecode/Opcode.h:
      (JSC):
      (JSC::padOpcodeName):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::emitCall):
      (JSC::BytecodeGenerator::emitCallVarargs):
      (JSC::BytecodeGenerator::emitConstruct):
      * bytecompiler/NodesCodegen.cpp:
      (JSC::NewExprNode::emitBytecode):
      (JSC::FunctionCallValueNode::emitBytecode):
      (JSC::FunctionCallResolveNode::emitBytecode):
      (JSC::FunctionCallBracketNode::emitBytecode):
      (JSC::FunctionCallDotNode::emitBytecode):
      (JSC::CallFunctionCallDotNode::emitBytecode):
      (JSC::ApplyFunctionCallDotNode::emitBytecode):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::ByteCodeParser):
      (ByteCodeParser):
      (JSC::DFG::ByteCodeParser::currentCodeOrigin):
      (JSC::DFG::ByteCodeParser::addCall):
      (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
      (JSC::DFG::ByteCodeParser::getPrediction):
      (JSC::DFG::ByteCodeParser::handleCall):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::handleMinMax):
      (JSC::DFG::ByteCodeParser::handleIntrinsic):
      (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::capabilityLevel):
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGOSRExitCompilerCommon.cpp:
      (JSC::DFG::reifyInlinedCallFrames):
      * jit/JIT.cpp:
      (JSC::JIT::privateCompileMainPass):
      * jit/JIT.h:
      (JIT):
      * jit/JITCall.cpp:
      (JSC::JIT::emitPutCallResult):
      (JSC::JIT::compileLoadVarargs):
      (JSC::JIT::compileCallEval):
      (JSC::JIT::compileCallEvalSlowCase):
      (JSC::JIT::compileOpCall):
      (JSC::JIT::compileOpCallSlowCase):
      (JSC::JIT::emit_op_call):
      (JSC):
      (JSC::JIT::emit_op_call_eval):
      (JSC::JIT::emit_op_call_varargs):
      (JSC::JIT::emit_op_construct):
      (JSC::JIT::emitSlow_op_call):
      (JSC::JIT::emitSlow_op_call_eval):
      (JSC::JIT::emitSlow_op_call_varargs):
      (JSC::JIT::emitSlow_op_construct):
      * jit/JITCall32_64.cpp:
      (JSC::JIT::emitPutCallResult):
      (JSC::JIT::compileLoadVarargs):
      (JSC::JIT::compileCallEval):
      (JSC::JIT::compileCallEvalSlowCase):
      (JSC::JIT::compileOpCall):
      (JSC::JIT::compileOpCallSlowCase):
      * jit/JITOpcodes.cpp:
      (JSC):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::genericCall):
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * llint/LowLevelInterpreter.cpp:
      (JSC::CLoop::execute):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153200 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      cf0e6c40
    • oliver@apple.com's avatar
      fourthTier: LLInt shouldn't store an offset call PC during op_call-like calls · dc48dc36
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=117048
      
      Reviewed by Mark Hahnenberg.
      
      This just makes everything consistent in the LLInt: anytime any op calls out,
      it stores its PC and never the next op's PC.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpBytecode):
      (JSC::CodeBlock::linkIncomingCall):
      (JSC::CodeBlock::bytecodeOffset):
      * bytecode/CodeBlock.h:
      * bytecode/Opcode.h:
      (JSC::padOpcodeName):
      * bytecompiler/BytecodeGenerator.cpp:
      (JSC::BytecodeGenerator::emitCallVarargs):
      * llint/LLIntExceptions.cpp:
      (JSC::LLInt::interpreterThrowInCaller):
      (JSC::LLInt::returnToThrow):
      (JSC::LLInt::callToThrow):
      * llint/LLIntSlowPaths.cpp:
      (JSC::LLInt::LLINT_SLOW_PATH_DECL):
      * llint/LowLevelInterpreter.asm:
      * llint/LowLevelInterpreter.cpp:
      (JSC::CLoop::execute):
      * llint/LowLevelInterpreter32_64.asm:
      * llint/LowLevelInterpreter64.asm:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153199 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      dc48dc36
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArithAbs · 0452e56c
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116890
      
      Reviewed by Oliver Hunt.
      
      Implements ArithAbs in the FTL, and cleans up the DFG implementation. The
      DFG implementation was previously doing zero extensions manually when it
      is probably better to just use StrictInt32Operand instead.
      
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLIntrinsicRepository.h:
      (FTL):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::doubleAbs):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153198 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      0452e56c
    • oliver@apple.com's avatar
      fourthTier: Misc JIT probe enhacements. · c3a5b8c5
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116586.
      
      Reviewed by Michael Saboff.
      
      1. Added JIT probe support for ARMv7 and traditional ARM.
         Built and tested on ARMv7. ARM version not tested nor built.
      2. Fix the following bugs in the X86 and X86_64 probes:
         a. Cannot assume that the stack pointer is already aligned when
            we push args for the probe. Instead, we ensure the stack
            alignment at runtime when we set up the probe call.
            This is now done in the ctiMasmProbeTrampoline.
         b. On return, the user probe function may have altered the stack
            pointer value to be restored. Previously, if the sp restore value
            points to some of the other register restore values in the
            ProbeContext record, we will fail to return from the probe having
            those user specified value as we're expected to do.
            This is now fixed.
      3. Rearranged the X86/X86_64 registers order to organize them like gdb
         expects on X86_64.
      4. We also now preserve the condition code registers.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * assembler/ARMAssembler.h:
      * assembler/ARMv7Assembler.h:
      (ARMRegisters):
      * assembler/MacroAssemblerARM.cpp:
      (JSC::isVFPPresent):
      (JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters):
      (JSC::MacroAssemblerARM::ProbeContext::dump):
      (JSC::MacroAssemblerARM::probe):
      * assembler/MacroAssemblerARM.h:
      (MacroAssemblerARM):
      (CPUState):
      (ProbeContext):
      (JSC::MacroAssemblerARM::trustedImm32FromPtr):
      * assembler/MacroAssemblerARMv7.h:
      (MacroAssemblerARMv7):
      (CPUState):
      (ProbeContext):
      (JSC::MacroAssemblerARMv7::trustedImm32FromPtr):
      * assembler/MacroAssemblerX86.h:
      (MacroAssemblerX86):
      (JSC::MacroAssemblerX86::probe):
      * assembler/MacroAssemblerX86Common.cpp:
      (JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters):
      * assembler/MacroAssemblerX86_64.h:
      (JSC::MacroAssemblerX86_64::probe):
      * assembler/X86Assembler.h:
      * config.h:
      * jit/JITStubsARM.h:
      * jit/JITStubsARMv7.h:
      * jit/JITStubsX86.h:
      * jit/JITStubsX86Common.h:
      * jit/JITStubsX86_64.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153197 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      c3a5b8c5
    • oliver@apple.com's avatar
      fourthTier: FTL should call masqueradesAsUndefinedWatchpointIfIsStillValid()... · 34c16e27
      oliver@apple.com authored
      fourthTier: FTL should call masqueradesAsUndefinedWatchpointIfIsStillValid() in all of the places where it currently calls masqueradesAsUndefinedWatchpointIsStillValid()
      https://bugs.webkit.org/show_bug.cgi?id=116892
      
      Reviewed by Oliver Hunt.
      
      All of those places mean to plant the watchpoint if it's still valid.
      
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
      (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153196 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      34c16e27
    • oliver@apple.com's avatar
      fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT · 920c78dc
      oliver@apple.com authored
      Rubber stamped by Oliver Hunt.
      
      * fast/js/dfg-arguments-alias-activation-expected.txt:
      * fast/js/dfg-arguments-alias-activation.html:
      * fast/js/dfg-arguments-alias-expected.txt:
      * fast/js/script-tests/dfg-arguments-alias.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153195 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      920c78dc
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArithMin/ArithMax · 61cccb84
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116885
      
      Reviewed by Oliver Hunt.
      
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153194 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      61cccb84
    • oliver@apple.com's avatar
      fourthTier: convert more fast/js/dfg-* tests to wait for the concurrent JIT · bd4b0fce
      oliver@apple.com authored
      Rubber stamped by Oliver Hunt.
      
      * fast/js/dfg-abs-backwards-propagation-expected.txt:
      * fast/js/dfg-add-not-number-expected.txt:
      * fast/js/dfg-arguments-alias-escape-expected.txt:
      * fast/js/resources/js-test-pre.js:
      (dfgCompiled):
      (dfgIncrement):
      * fast/js/script-tests/dfg-abs-backwards-propagation.js:
      * fast/js/script-tests/dfg-add-not-number.js:
      * fast/js/script-tests/dfg-arguments-alias-escape.js:
      * fast/js/script-tests/dfg-arguments-alias-one-block-osr-exit.js:
      * fast/js/script-tests/dfg-arguments-alias-one-block-overwrite-arguments.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153193 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      bd4b0fce
    • oliver@apple.com's avatar
      fourthTier: fast/js should have a way of running tests long enough to wait for... · 52619b34
      oliver@apple.com authored
      fourthTier: fast/js should have a way of running tests long enough to wait for the concurrent JIT to tier up
      https://bugs.webkit.org/show_bug.cgi?id=116878
      
      Reviewed by Oliver Hunt.
      
      This adds three things to js-test-pre and uses them in one representative test:
      
      silentTestPass: If you set this to true, then testPassed() won't print anything, and will instead just have
          isSuccessfullyParsed() print a message saying that some tests passed silently. This allows tests to call
          shouldBe() and friends in a loop whose running time is dependent on concurrent JIT behavior, and still
          be sure that the resulting test will be deterministic.
      
      noInline(): If testRunner is present, disable inlining of the relevant function.
      
      dfgIncrement({f:function, i:index, n:limit}): Returns index either if index < limit, or if the function is
          DFG compiled. Otherwise, if index >= limit and the function isn't DFG compiled, return 0. This means
          that the 'i++' in the fast/js/dfg-* warm-up loops can be replaced with:
      
          i = dfgIncrement({f:<function you're interested in>, i:i + 1, n:<some number smaller than the loop condition>)
      
          This has the effect of having the loop repeat the first 'n' iterations until the function is DFG
          compiled. See the modified test, where we do n:100 and the loop condition is i < 200. So the loop will
          repeat the first 100 iterations until the function is DFG compiled and will only do the last 100
          iterations once DFG compilation kicks in.
      
      * fast/js/dfg-arguments-osr-exit-multiple-blocks-expected.txt:
      * fast/js/resources/js-test-pre.js:
      (testPassed):
      (dfgIncrement):
      (noInline):
      (isSuccessfullyParsed):
      * fast/js/script-tests/dfg-arguments-osr-exit-multiple-blocks.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153192 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      52619b34
    • oliver@apple.com's avatar
      fourthTier: testRunner should have a way of disabling inlining of functions · 4e67ae52
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116875
      
      Reviewed by Mark Hahnenberg.
      
      Source/JavaScriptCore:
      
      * API/JSCTestRunnerUtils.cpp:
      (JSC::getExecutable):
      (JSC):
      (JSC::numberOfDFGCompiles):
      (JSC::setNeverInline):
      * API/JSCTestRunnerUtils.h:
      (JSC):
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpAssumingJITType):
      * dfg/DFGCapabilities.cpp:
      (JSC::DFG::mightInlineFunctionForCall):
      (JSC::DFG::mightInlineFunctionForClosureCall):
      (JSC::DFG::mightInlineFunctionForConstruct):
      * runtime/Executable.h:
      (JSC::ScriptExecutable::ScriptExecutable):
      (ScriptExecutable):
      (JSC::ScriptExecutable::setNeverInline):
      (JSC::ScriptExecutable::neverInline):
      (JSC::ScriptExecutable::isInliningCandidate):
      
      Tools:
      
      * DumpRenderTree/TestRunner.cpp:
      (neverInlineFunction):
      (TestRunner::staticFunctions):
      
      LayoutTests:
      
      * fast/js/script-tests/dfg-min-max.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153191 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4e67ae52
    • oliver@apple.com's avatar
      fourthTier: FTL should support ArithMod · d533b183
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116792
      
      Reviewed by Oliver Hunt.
      
      * ftl/FTLAbbreviations.h:
      (JSC::FTL::buildFRem):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileArithMod):
      (LowerDFGToLLVM):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::doubleRem):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153190 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      d533b183
    • oliver@apple.com's avatar
      fourthTier: It should be possible to record heap operations (both FastMalloc and JSC GC) · a03796ac
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116848
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Record GC heap operations if ENABLE(ALLOCATION_LOGGING).
      
      * API/JSManagedValue.mm:
      * dfg/DFGOperations.cpp:
      * heap/Heap.cpp:
      (JSC::Heap::collect):
      * heap/Heap.h:
      (Heap):
      (JSC::Heap::allocateWithNormalDestructor):
      (JSC::Heap::allocateWithImmortalStructureDestructor):
      (JSC::Heap::allocateWithoutDestructor):
      (JSC::Heap::tryAllocateStorage):
      (JSC::Heap::tryReallocateStorage):
      (JSC):
      (JSC::Heap::ascribeOwner):
      * heap/SlotVisitor.cpp:
      (JSC::SlotVisitor::append):
      (JSC::SlotVisitor::internalAppend):
      * heap/SlotVisitor.h:
      (SlotVisitor):
      * heap/SlotVisitorInlines.h:
      (JSC::SlotVisitor::append):
      (JSC::SlotVisitor::appendUnbarrieredPointer):
      (JSC::SlotVisitor::appendUnbarrieredValue):
      (JSC::SlotVisitor::appendUnbarrieredWeak):
      (JSC::SlotVisitor::internalAppend):
      (JSC):
      (JSC::SlotVisitor::appendValues):
      * jit/JITWriteBarrier.h:
      (JSC::SlotVisitor::append):
      * llint/LLIntCommon.h:
      * runtime/Butterfly.h:
      (Butterfly):
      * runtime/ButterflyInlines.h:
      (JSC::Butterfly::createUninitialized):
      (JSC::Butterfly::create):
      (JSC::Butterfly::growPropertyStorage):
      (JSC::Butterfly::createOrGrowArrayRight):
      (JSC):
      (JSC::Butterfly::growArrayRight):
      (JSC::Butterfly::resizeArray):
      * runtime/JSArray.cpp:
      (JSC::createArrayButterflyInDictionaryIndexingMode):
      (JSC::JSArray::unshiftCountSlowCase):
      * runtime/JSArray.h:
      (JSC::createContiguousArrayButterfly):
      (JSC::createArrayButterfly):
      (JSC):
      (JSC::JSArray::create):
      (JSC::JSArray::tryCreateUninitialized):
      * runtime/JSObject.cpp:
      (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
      (JSC::JSObject::createInitialIndexedStorage):
      (JSC::JSObject::createArrayStorage):
      (JSC::JSObject::constructConvertedArrayStorageWithoutCopyingElements):
      (JSC::JSObject::increaseVectorLength):
      (JSC::JSObject::ensureLengthSlow):
      (JSC::JSObject::growOutOfLineStorage):
      * runtime/JSObject.h:
      (JSC::JSObject::JSObject):
      * runtime/Operations.h:
      * runtime/RegExpMatchesArray.cpp:
      (JSC::RegExpMatchesArray::create):
      * runtime/StructureInlines.h:
      (JSC):
      * runtime/WriteBarrier.h:
      (JSC):
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/DataLog.cpp:
      (WTF):
      (WTF::initializeLogFileOnce):
      * wtf/FastMalloc.cpp:
      (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
      * wtf/Platform.h:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153189 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      a03796ac
    • oliver@apple.com's avatar
      fourthTier: testRunner should be able to tell you if a function is DFG compiled · 37172f80
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116847
      
      Reviewed by Mark Hahnenberg.
      
      Source/JavaScriptCore:
      
      * API/JSCTestRunnerUtils.cpp: Added.
      (JSC):
      (JSC::numberOfDFGCompiles):
      * API/JSCTestRunnerUtils.h: Added.
      (JSC):
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::numberOfDFGCompiles):
      (JSC):
      * bytecode/CodeBlock.h:
      (CodeBlock):
      * dfg/DFGWorklist.cpp:
      (JSC::DFG::Worklist::runThread):
      * runtime/Executable.h:
      (JSC):
      * runtime/JSFunctionInlines.h: Added.
      (JSC):
      (JSC::JSFunction::JSFunction):
      (JSC::JSFunction::jsExecutable):
      (JSC::JSFunction::isHostFunction):
      (JSC::JSFunction::nativeFunction):
      (JSC::JSFunction::nativeConstructor):
      * runtime/Operations.h:
      
      Source/WebCore:
      
      Bail early if we're in the compilation thread. This is only relevant for
      debug dumps.
      
      No new tests becase no new behavior.
      
      * loader/cache/CachedScript.cpp:
      (WebCore::CachedScript::script):
      
      Tools:
      
      * DumpRenderTree/TestRunner.cpp:
      (numberOfDFGCompiles):
      (TestRunner::staticFunctions):
      
      LayoutTests:
      
      * fast/js/script-tests/dfg-min-max.js:
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153188 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      37172f80
    • oliver@apple.com's avatar
      fourthTier: DFG ArithMod should have the !nodeUsedAsNumber optimizations that ArithDiv has · 34a59ca9
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116841
      
      Reviewed by Mark Hahnenberg.
      
      Source/JavaScriptCore:
      
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileArithMod):
      
      LayoutTests:
      
      * fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
      * fast/js/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.html: Added.
      * fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc-expected.txt: Added.
      * fast/js/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.html: Added.
      * fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc-expected.txt: Added.
      * fast/js/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-mod-by-neg1-and-then-or-zero-interesting-reg-alloc.js: Added.
      (foo):
      * fast/js/script-tests/dfg-mod-by-zero-and-then-or-zero-interesting-reg-alloc.js: Added.
      (foo):
      * fast/js/script-tests/dfg-mod-neg2tothe31-by-one-and-then-or-zero-with-interesting-reg-alloc.js: Added.
      (foo):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153187 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      34a59ca9
    • oliver@apple.com's avatar
      fourthTier: clean up ArithDiv/ArithMod in the DFG · f4443a7b
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=116793
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      This makes ArithDiv and ArithMod behave similarly, and moves both of their
      implementations entirely into DFGSpeculativeJIT.cpp into methods named like
      the ones for ArithSub/ArithMul.
      
      Specifically, ArithMod now uses the wrap-in-conversion-nodes idiom that
      ArithDiv used for platforms that don't support integer division. Previously
      ArithMod had its own int-to-double and double-to-int conversions for this
      purpose.
      
      As well, this gets rid of confusing methods like compileSoftModulo() (which
      did no such thing, there wasn't anything "soft" about it) and
      compileIntegerArithDivForX86() (which is accurately named but we don't use
      the platform-specific method convention anywhere else).
      
      Finally, this takes the optimized power-of-two modulo operation that was
      previously only for ARMv7s, and makes it available for all platforms. Well,
      sort of: I actually rewrote it to do what latest LLVM appears to do, which
      is a crazy straight-line power-of-2 modulo based on a combination of shifts,
      ands, additions, and subtractions. I can kind of understand it well enough
      to see that it complies with both C and JS power-of-2 modulo semantics. I've
      also confirmed that it does by testing (hence the corresponding improvements
      to one of the division tests). But, I don't claim to know exactly how this
      code works other than to observe that it is super leet.
      
      Overall, this patch has the effect of killing some code (no more hackish
      int-to-double conversions in ArithMod), making some optimization work on
      more platforms, and making the compiler less confusing by doing more things
      with the same idiom.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGSpeculativeJIT.cpp:
      (DFG):
      (JSC::DFG::SpeculativeJIT::compileArithDiv):
      (JSC::DFG::SpeculativeJIT::compileArithMod):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      
      LayoutTests:
      
      Reviewed by Mark Hahnenberg.
      
      * fast/js/script-tests/integer-division-neg2tothe32-by-neg1.js:
      (myModBy2):
      (myModBy1073741824):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153186 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      f4443a7b